uniapp u--input实现select下拉列表 input点击事件

news2024/9/24 7:15:03

背景:

技术框架:

uniapp框架(vue2语法)+uView组件库。

通过form表单实现数据列表的“查询”功能。注意:

1、<u--form>内部嵌套<u-form-item>,<u-form-item>内部嵌套<u--input>表单组件。

2、H5浏览器端,input输入框可以整块点击。但uniapp打包成App,不能整块点击;在平板上运行,可以整块点击。

3、input实现 select下拉列表功能

4、在App上,实现input输入框的整块点击,点击之后出现select弹框区域。

5、Form表单封装组件。接收绑定Form的数据(父传子formItems[]);监听formInline的变化,监听到变化后emit(子传父,)

 

效果展示:

 

官网链接:点击跳转官网 form

 接下来便是要解决的问题:让整块input输入框都可以点击。。。

 一、selet下拉列表的实现

实现思路:

input输入框,通过点击右侧的插槽图标,实现select弹框弹出。实际是两部分组成。。。

<u--input 
    :readonly="true" 
    v-model="inputValue" 
    :placeholder="'请选择'"
    suffixIcon="arrow-down" 
>
</u--input>

下拉列表:

<!-- 下拉列表显示 -->
<u-action-sheet 
    :show="showOption" 
    :actions="currentSelectItem.option.optionList"
    :title="currentSelectItem.option.title" 
    :description="currentSelectItem.option.description"
    @close="handleCloseOption(false)" 
    @select="handleSelect" 
    v-if="currentSelectItem.option"
>
</u-action-sheet>

官网链接:点击跳转官网 action-sheet

 

二、input框整块点击,打开select弹框

实现思路:

要想实现input框的整块点击。

实现思路是:

1、给当前input外层套一个盒子,在此盒子上绑定@click事件;

2、给input添加鼠标点击样式:style="pointer-events:none"。

none表示:鼠标事件“穿透”该元素并且指定该元素“下面”的任何东西。

给input外层套一层盒子,并绑定事件:

<template @click='handleOpenOption(item)'>
<u--input 
:readonly="true" 
style="pointer-events:none" 
v-model="inputValue"				
:placeholder="'整块点击'" 
suffixIcon="arrow-down" 
>
</u--input>
</template>

 事件:

methods: {
		handleOpenOption(item) {
			if (item.type === 'calendar') {
				this.currentSelectItem = {
					...item
				};
				this.handleCloseCalendar(true);//打开日期选择弹框
			}
			if (item.type === 'select') {
				this.currentSelectItem = {
					...item
				};
				this.handleCloseOption(true);//打开select弹框
			}
		},
}

三、封装form表单组件

背景:

理论知识:

父传子:通过props,获取到传递到子组件的formItems[];

子传父:通过watch监听表单组件绑定的数据的变化,使用emit('自定义事件名',传给父组件的数据值)

图片:

 formItems封装代码:

//formItems分装代码
<template>
	<view>
		<u--form labelPosition="left" :model="formInline" :rules="formRules" ref="uForm" :errorType="errorType">
			<u-form-item :required="item.rule.required" labelWidth="230rpx" labelAlign="right" :label="item.label"
				:prop="item.key" :borderBottom="false" @tap="handleOpenOption(item)" v-for="item, index in formItems"
				:key="index">
				<u--input v-model="formInline[item.key]" :placeholder="item.placeholder" v-if="item.type === 'input'"
					:customStyle="item.customStyle"></u--input>
				<!-- input带后置图标 -->
				<u--input v-model="formInline[item.key]" :placeholder="item.placeholder" suffixIcon="search"
					suffixIconStyle="color: #333333;font-size: 42rpx" v-if="item.type === 'input2'"
					:customStyle="item.customStyle" :clearable="true" @clear="handleClear(item.key)"></u--input>
				<!-- 以下点击设置hideKeyboard(),让移动端不弹出键盘 -->
				<template @click='handleOpenOption(item)'>
					<u--input :readonly="true" style="pointer-events:none" v-model="formInline[item.key].name"
						:placeholder="item.placeholder" suffixIcon="arrow-down" v-if="item.type === 'select'"
						:customStyle="item.customStyle"></u--input>
				</template>
				<template @click='handleOpenOption(item)'>
					<u--input :readonly="true" style="pointer-events:none" v-model="formInline[item.key]"
						:placeholder="item.placeholder" suffixIcon="clock" v-if="item.type === 'calendar'"
						:customStyle="item.customStyle" :clearable="true" @clear="handleClear(item.key)" ></u--input>
				</template>
			</u-form-item>
		</u--form>
		<!-- 下拉列表显示 -->
		<u-action-sheet :show="showOption" :actions="currentSelectItem.option.optionList"
			:title="currentSelectItem.option.title" :description="currentSelectItem.option.description"
			@close="handleCloseOption(false)" @select="handleSelect" v-if="currentSelectItem.option">
		</u-action-sheet>
		<!-- 日历显示 -->
		<u-calendar :closeOnClickOverlay="true" monthNum="12" :minDate="minDate" :maxDate="maxDate" :show="showCalendar"
			mode="range" :allowSameDay="true" @confirm="handleConfirmCalendar"
			@close="handleCloseCalendar(false)"></u-calendar>
	</view>
</template>

<script>
import {
	getLayerData
} from '@/api/index.js'

export default {
	name: "FormItem",
	data() {
		return {
			formInline: {},
			formRules: {},

			showOption: false,
			currentSelectItem: {},
			showCalendar: false,
			readonlyCalendar: true,
			minDate: '2023-01-01',
			maxDate: '2023-11-07',
		};
	},
	props: {
		formItems: Array,
		errorType: {
			type: String,
			default: 'none'
		}
	},
	computed: {},
	watch: {
		formItems: {
			immediate: true,
			handler(newval, oldval) {
				newval.forEach(item => {
					// 动态请求下拉列表
					(item.type === 'select' && item.option.optionsSrc) && this.getOptionList(item);
					this.getFormRules();
					this.getFormInlineDefault();
				});
			}
		},
		formInline: {
			immediate: true,
			deep: true,
			handler(newval, oldval) {
				this.$emit('searchData', newval);
			}
		}
	},
	methods: {
		handleConfirmCalendar(e) { //日历选项选择完毕确认
			this.formInline[this.currentSelectItem.key] = e[0] + '至' + e[e.length - 1]
			this.handleCloseCalendar(false);
			// this.readonlyCalendar = !this.readonlyCalendar;
		},
		handleCloseCalendar(state) { //日历选项关闭
			this.showCalendar = state;
		},

		handleOpenOption(item) {
			if (this.readonlyCalendar) {
				if (item.type === 'calendar') {
					this.currentSelectItem = {
						...item
					};
					this.handleCloseCalendar(true);
				}
			}
			if (item.type === 'select') {
				//当前选择框的信息,因为复用了同一个下拉选择弹出层
				this.currentSelectItem = {
					...item
				};
				this.handleCloseOption(true);
			}
		},
		handleSelect(e) { //下拉选项选择目标逻辑
			this.formInline[this.currentSelectItem.key] = e;
		},
		handleCloseOption(state) { //下拉选项关闭逻辑
			this.showOption = state;
		},
		async getOptionList(item) {
			const {
				data: res
			} = await getLayerData(item.option.optionsSrc);
			const resData = res.data;
			item.option.optionList = resData.reduce((cre, pre) => [...cre, {
				name: pre[item.option.optionContent.name],
				// 下拉选项是对各值还是一个值
				value: item.option.optionContent.value === 'objString' ? JSON.stringify(pre) : pre[
					item.option.optionContent.value]
			}], [...item.option.options]);

			this.getFormInlineDefault();
		},
		getFormInlineDefault() {
			this.formInline = this.formItems.reduce((cre, pre) => {
				let handlePre = '';
				if (pre.defaultVal) {
					if (pre.defaultVal instanceof Array) {
						// 动态请求的内容作为默认值
						if (pre.option.optionList?.length > pre.defaultVal[0]) {
							handlePre = pre.option.optionList[pre.defaultVal[0]];
						} else {
							const emptyTarget = pre.option.optionList?.find(item => item.value === '')
							handlePre = emptyTarget || '';
						}
					} else {
						handlePre = pre.defaultVal;
					}
				} else {
					// const emptyTarget = pre.option?.optionList?.find(item => item.value === '')
					// handlePre = emptyTarget || '';
					handlePre = ''
				}
				return {
					...cre,
					[pre.key]: handlePre
				}
			}, {});
		},
		getFormRules() {
			this.formRules = this.formItems.reduce((cre, pre) => {
				return pre.rule && {
					...cre,
					[pre.key]: pre.rule
				}
			}, {});
		},
		handleClear(_key) {
			this.formInline[_key] = '';
			this.readonlyCalendar = true;
			this.readonlySelect = true
		},
		clickshowOption() {
			this.showOption = !this.showOption
		},
		getCurrentData() {
			const d = new Date()
			const year = d.getFullYear()
			let month = d.getMonth() + 1
			month = month < 10 ? `0${month}` : month
			const date = d.getDate()
			return [`${year}-${month}-${date}`]
		},
		getMinDate(_yesteMonth) {
			const yesteMonth = _yesteMonth || 2
			const d = new Date()
			const year = d.getFullYear()
			let month = d.getMonth() - yesteMonth
			month = month < 10 ? `0${month}` : month
			const date = d.getDate()
			return `${year}-${month}-${date}`
		}
	},
	onLoad() {
		this.formInline = {}
	},
	created() {
		this.maxDate = this.getCurrentData()[0]
		this.minDate = this.getMinDate(6)
	}
}
</script>

<style scoped lang="scss">
/deep/.u-form {

	>.u-form-item {

		>.u-form-item__body {
			padding: 0;

			>.u-form-item__body__right {
				// background-color: #F6F7FA;
				/* border-radius: 12rpx;
					border: 1px solid #E3E7EE;
					padding: 10rpx; */
			}
		}
	}
}

// /deep/ .u-input__content__clear {
// 	position: relative;
// }

// /deep/.u-icon__icon {
// 	position: absolute;
// 	left: 0px;
// 	right: 0px;
// 	top: 0px;
// 	bottom: 0px;
// 	justify-content: center;
// }</style>

父组件使用方法:

//父传子myformItems
//子传父触发事件mysearchData
<FormItem :formItems="myformItems" @searchData="mysearchData"></FormItem>

上面用到的数据和方法:

数据formItems,示例如下:

[
    {
      type: "input2",
      // label: "船舶名称",
      key: "name",
      placeholder: "请输入船舶名称",
      rule: {
        required: false,
      },
      customStyle: {
        "margin-bottom": "20rpx",
      },
    },
    {
      type: "input2",
      // label: "MMSI",
      key: "mmsi",
      placeholder: "请输入MMSI",
      rule: {
        required: false,
      },
      customStyle: {
        "margin-bottom": "20rpx",
      },
    },
  ],

 mysearchData事件,示例如下:

methods: {
        mysearchData(_data) {
            console.log(_data);
            this.pages.name = _data.name
            this.pages.mmsi = _data.mmsi
            this.pages.pageNum = 1
            this.pages.pageSize = 7
            this.getTableList(this.pages)//查询接口
         }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2093675.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为 HCIP-Datacom H12-821 题库

有需要题库的可以看主页置顶 1.MSTP 有不同的端口角色&#xff0c;对此说法不正确的是&#xff1a; A、MSTP 中除边缘端口外&#xff0c;其他端口角色都参与 MSTP 的计算过程 B、MSTP 同一端口在不同的生成树实例中可以担任不同的角色。 C、MSTP 域边缘端口是指位于 MST 域的边…

QT实战项目之音乐播放器

项目效果演示 myMusicShow 项目概述 在本QT音乐播放器实战项目中&#xff0c;开发环境使用的是QT Creator5.14版本。该项目实现了音乐播放器的基本功能&#xff0c;例如开始播放、停止播放、下一首播放、上一首播放、调节音量、调节倍速、设置音乐播放模式等。同时还具备搜索功…

SPR系列单点激光测距传感器|模组之RS485串口调试说明

SPR系列单点激光测距传感器|模组是一款近程红外测距传感器&#xff0c;测距距离可达0-10米&#xff0c;可用于对物体进行非接触式距离测量&#xff0c;其应用场景十分广泛工业自动化&#xff1a;在生产线、传送带等工业自动化场景中&#xff0c;可以使用红外测距传感器进行物体…

Git安装及配置

Git安装 在你开始使用 Git 前,需要将它安装在你的计算机上。 即便已经安装,最好将它升级到最新的版本。 你可以通过软件包或者其它安装程序来安装,或者下载源码编译安装。 下面,我们将会介绍不同操作系统上 Git 的安装方法。 在 Windows 上安装 在 Windows 上安装 Git 的…

LangChain基础知识

这篇文档介绍了LangChain大模型应用开发框架的入门知识和核心内容&#xff0c;包括LangChain是什么、为什么需要它、典型使用场景、基础概念与模块化设计等。同时&#xff0c;还详细阐述了该框架的核心模块如标准化的大模型抽象、大模型应用的最佳实践、赋予应用记忆的能力、框…

JDBC |封装JDBCUtils|PreparedStatement|事务|批处理|数据库连接池| Blob类型数据的读写|Apache—DBUtils简介

一.概述 在Java中&#xff0c;数据库存取技术可分为如下几类&#xff1a; JDBC直接访问数据库JDO技术&#xff08;Java Data Object&#xff09;第三方O/R工具&#xff0c;如Hibernate, Mybatis 等 JDBC是java访问数据库的基石&#xff0c;JDO, Hibernate等只是更好的封装了J…

计算多图的等价无向图的邻接链表表示

计算多图的等价无向图的邻接链表表示 摘要:一、引言二、算法思路三、伪代码实现四、C代码实现五、算法分析六、结论摘要: 在图论中,多图(Multigraph)是一种允许边重复以及存在自循环边(即一个顶点到其自身的边)的图。给定一个多图的邻接链表表示,本文旨在探讨如何构造…

用EA和SysML一步步建模(03)创建包图和包的关系

用EA和SysML一步步建模的操作指南&#xff08;01&#xff09; 用EA和SysML一步步建模&#xff08;02&#xff09;导入ISO-80000 接下来&#xff0c;按照下图添加上其他的包&#xff1a; 步骤 2.2 选中Browser中的“蒸馏器项目”&#xff0c;点击New Package&#xff08;Br…

windows C++ 并行编程-C++ AMP 图形(二)

文中的"显存"还没有找到合适的中文翻译&#xff0c;它的英文名称是texture&#xff0c; 在应用开发者来看,texture是一个名词,在物理上指的是 GPU显存中一段连续的空间。 读取显存对象 可以使用 texture::operator[]、texture::operator() 运算符或 texture::get 方…

物流需求回复势头稳定,目前全国社会物流总额达197.7万亿元

中国物流与采购联合会29日公布今年1-7月份物流运行数据。数据显示&#xff0c;物流需求恢复势头基本稳定&#xff0c;7月份虽受部分地区高温多雨等短期因素扰动&#xff0c;但物流总额增速环比有所提升&#xff0c;呈现温和回升态势。 今年1-7月份&#xff0c;全国社会物流总额…

数据仓库系列17:元数据管理在数据仓库中的作用是什么?

想象一下,你正在管理一个巨大的图书馆,里面存放着数以万计的书籍。但是,这个图书馆没有任何目录、索引或分类系统。你能想象找到特定的一本书会有多困难吗?这就是没有元数据管理的数据仓库的真实写照。 目录 什么是元数据?元数据管理的重要性元数据在数据仓库中的类型1. 技术…

Open3D mesh Taubin滤波

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 参数详解 返回值 2.2完整代码 三、实现效果 3.1加入噪声的mesh 3.2Taubin迭代10次 3.3Taubin迭代100次 Open3D点云算法汇总及实战案例汇总的目录地址&#xff1a; Open3D点云算法与点云…

【学习笔记】卫星通信发展趋势

卫星通信系统是融合现代通信技术、航天技术与计算机技术的综合应用&#xff0c;已成为国际与国内通信、国防、移动通信及广播电视领域的关键基础设施。基于其频带宽度大、通信容量高、业务兼容性强、覆盖范围广、性能稳定、地理条件适应性高及成本与距离无关等特性&#xff0c;…

猫咪浮毛不再乱飞 希喂、霍尼韦尔、352宠物空气净化器功能实测

“你真的养猫了吗&#xff1f;为什么一点也看不出来&#xff1f;”养宠以来我经常收到这样的提问&#xff0c;原因是另一位铲屎官身上总会时不时出现猫咪毛发&#xff0c;标记着他的身份。哪有不会掉毛的猫咪呢&#xff0c;何况到了夏天&#xff0c;换毛季的掉毛量更是惊人。其…

KTV开台源码--SAAS本地化及未来之窗行业应用跨平台架构

一、ktv开台源码 function 未来之窗_人工智能_KTV开台(title,桌台id,类型id,类型名称){var 未来之窗app_通用ID"未来之城激光加工机";var 未来之窗_人工智能_内容 tpl_未来之窗_模板_KTV开单;CyberWin_Dialog.layer(未来之窗_人工智能_内容,{type:"frame",…

Kubernetes 网关流量管理:Ingress 与 Gateway API

引言 随着 Kubernetes 在云原生领域的广泛使用&#xff0c;流量管理成为了至关重要的一环。为了有效地管理从外部流入集群的流量&#xff0c;Kubernetes 提供了多种解决方案&#xff0c;其中最常见的是 Ingress 和新兴的 Gateway API。 Ingress 随着微服务架构的发展&#x…

【手撕数据结构】二叉树的性质

目录 叶子节点和边的性质概念小试牛刀 叶子节点和边的性质 概念 可以看到度为0的节点如F没有边&#xff0c;度为1的节点如C有一条边&#xff0c;而度为2的节点如B有两条边。那么设度为2的节点为a个&#xff0c;度为1的节点为b个。二叉树边 2ab另⼀⽅⾯&#xff0c;由于共有 a…

反激式开关电源(硬件面试86题 电源专栏)

在硬件面试经典中的第 86 题中提到的反激式开关电源&#xff0c;是通过开关通断将交流转变成直流的 AD-DC 开关电源的一种&#xff0c;并且反激式开关电源是由 BUCK-BOOST 电路演变而来&#xff0c;所以博客由浅入深一步一步讲解完反激式开关的知识&#xff0c;让我们开始吧&am…

未使用CMSIS之前的stm32标准库中SystemHandler的宏定义

背景&#xff1a; 在stm32的标准库还叫STM32F10xxx_FWLib_V2.0.3的那个年代 文件 STM32F10xFWLib_V2.0.3/FWLib/library/inc/stm32f10x_nvic.h 中有对System Handlers的定义。具体内容如下&#xff1a; /* System Handlers -------------------------------------------------…

【Python】2.基础语法(2)

文章目录 1.顺序语句2.条件语句2.1语法格式2.1.1 if2.1.2 if - else2.1.3 if - elif - else 2.2缩进和代码块2.3 空语句 pass 3. 循环语句3.1 while 循环3.2 for 循环3.3 continue3.4 break 4. 综合案例4.1 设置初始属性4.2 设置性别4.3 设置出生点4.4 针对每一岁, 生成人生经历…