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

news/2024/9/18 15:07:23/ 标签: uni-app

背景:

技术框架:

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() + 1month = month < 10 ? `0${month}` : monthconst date = d.getDate()return [`${year}-${month}-${date}`]},getMinDate(_yesteMonth) {const yesteMonth = _yesteMonth || 2const d = new Date()const year = d.getFullYear()let month = d.getMonth() - yesteMonthmonth = month < 10 ? `0${month}` : monthconst 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.namethis.pages.mmsi = _data.mmsithis.pages.pageNum = 1this.pages.pageSize = 7this.getTableList(this.pages)//查询接口}
}


http://www.ppmy.cn/news/1517139.html

相关文章

HTTP 414错误问题

问题描述&#xff1a; 在一次前端编辑报表完成&#xff0c;打开审核人选择弹出框的时候&#xff0c;layer直接报414错误。 问题分析&#xff1a; HTTP 414是HTTP协议中的一个状态码&#xff0c;表示请求的URI&#xff08;Uniform Resource Identifier&#xff09;过长&#…

海睿思通过华东江苏大数据交易中心数商认证,提供高质量数据治理服务!

近日&#xff0c;中新赛克海睿思成功通过华东江苏大数据交易中心的数商认证&#xff0c;获得华东江苏大数据交易中心颁发的“数据治理服务商”证书。 华东数交是在实施“国家大数据战略”大背景下&#xff0c;经国家批准的华东地区首个省级特色数据要素交易平台&#xff0c;致力…

美客多卖家如何借助自养号测评提升销量

在美客多这一电商平台上&#xff0c;尽管当前多数卖家尚未充分利用测评技术&#xff0c;但其作为低成本、高回报的推广方式&#xff0c;无疑蕴藏着巨大的市场潜力。面对竞争相对缓和的市场环境及卖家对测评概念的普遍忽视&#xff0c;以下是对测评技术重要性的强调及其实施策略…

Adobe After Effects的插件--------CC Ball Action

CC Ball Action是粒子效果器,其将2D图层变为一个个由3D小球构成的图层。它是AE内置的3D插件。 使用条件 使用该插件的图层需是2D图层。 我们以一张图片素材为例: 给图片图层添加CC Ball Action效果控件,然后新建一个摄像机(利用摄像机旋转、平移、推拉工具,方便在各个角…

Spark MLlib 特征工程系列—特征转换VectorSizeHint

Spark MLlib 特征工程系列—特征转换VectorSizeHint VectorSizeHint 是 Spark 提供的一个特征转换器,用于指定向量列的大小(即维度)。在一些特征转换和建模过程中,要求输入的向量必须有固定的大小。当数据中包含不同大小的向量时,Spark 可能无法自动推断出向量的正确大小…

基于Vue3和Node.js的完整增删改查项目实现教程:从后端封装到前端调用

在 Node.js 中封装一个增删改查&#xff08;CRUD&#xff09;接口&#xff0c;并在 Vue 3 前端调用这些接口。整个过程包括后端 API 的创建和前端的调用。 一、安装 Node.js 和 Express 脚手架 1. 安装 Node.js 首先&#xff0c;你需要安装 Node.js。你可以通过以下步骤进行安…

零基础入门转录组数据分析——预后模型之多因素cox模型

零基础入门转录组数据分析——预后模型之多因素cox模型 目录 零基础入门转录组数据分析——预后模型之多因素cox模型1. 预后模型和多因素cox模型基础知识2. 多因素cox预后模型&#xff08;Rstudio&#xff09;——代码实操2. 1 数据处理2. 2 构建多因素cox模型&#xff08;用输…

如何构建社区康养管理系统?实现老年人服务管理全攻略【Java SpringBoot】

✍✍计算机毕业编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java、…

【Go语言成长之路】多模块工作区入门

文章目录 【Go语言成长之路】多模块工作区入门前提条件一、创建一个模块二、创建工作空间三、创建第二个模块四、更多关于workspace 【Go语言成长之路】多模块工作区入门 ​ 多模块工作区(muti-module workspaces)可以使得开发者在多个模块中构建并且运行代码&#xff0c;相互…

在浏览器上使用transformers.js运行(WebGPU)RMBG-1.4进行抠图(背景移除)

在浏览器上使用transformers.js运行&#xff08;WebGPU&#xff09;RMBG-1.4进行抠图&#xff08;背景移除&#xff09; 说明&#xff1a; 首次发表日期&#xff1a;2024-08-28官方Github仓库地址&#xff1a; https://github.com/xenova/transformers.js/tree/main/examples…

《深入浅出WPF》读书笔记.8路由事件

《深入浅出WPF》读书笔记.8路由事件 背景 路由事件是直接响应事件的变种。直接响应事件&#xff0c;事件触发者和事件响应者必须显示订阅。而路由事件的触发者和事件响应者之间的没有显示订阅&#xff0c;事件触发后&#xff0c;事件响应者安装事件监听器&#xff0c;当事件传…

SpringBoot -在Axis2中,RPCServiceClient调用WebService

在 Axis2 中,RPCServiceClient 是一种用于调用 WebService 的客户端实现。下面是如何将它们 结合起来使用的一个示例: 步骤 1: 添加依赖 首先,在 pom.xml 文件中添加 Axis2 的相关依赖。 <dependencies><!-- 其他依赖 --><dependency><groupId>…

拓扑排序-

基本原理 就是存在一个入度为0的点和一个出度为0的点 然后图中所有点都是指向同一个方向&#xff1b; /* 拓扑序列&#xff1a; 特点&#xff1a;有向无环图 判断&#xff1a;判断所有的点是否入度为0 换句话 就是入度为0的点个数是否满点的总数 过程&#xff1a;建图、入度数…

2024HarmonyOS应用开发者高级认证最新整理题库和答案(已收录182道 )

更新截止2024-08-27,完整题库一共182道题,足够覆盖90%考题,如有新题和遗漏我会持续补充 所有题目的选项都是打乱顺序的,记答案不要记序号 完整题库请在我的网盘下载或查看在线文档 完整题库在线文档预览 单选(已收录102道) 1 . 以下哪个装饰器用来表示并发共享对象。(B) A. @…

通过Python绘制不同数据类型适合的可视化图表

在数据可视化中&#xff0c;对于描述数值变量与数值变量之间的关系常见的有散点图和热力图&#xff0c;以及描述数值变量与分类变量之间的关系常见的有条形图&#xff0c;饼图和折线图&#xff0c;可以通过使用Python的matplotlib和seaborn库来绘制图表进行可视化表达&#xff…

超详细!!!uniapp通过unipush全流程实现app消息推送

云风网 云风笔记 云风知识库 一、HBuilder新建APP项目 二、配置推送服务 1、登录Dcloud开发者中心开发者中心&#xff0c;查看我的应用 2、生成云端证书 3、创建平台信息 4、配置推送服务信息 这里需要关联服务空间&#xff0c;可以申请免费服务空间进行测试 三、代码配置 1…

Java笔试面试题AI答之线程(24)

文章目录 139. 简述为什么 wait(), notify()和 notifyAll()必须在同步方法或 者同步块中被调用&#xff1f;140. 简述为什么 Thread 类的 sleep()和 yield ()方法是静态的 &#xff1f;1. sleep() 方法2. yield() 方法总结 141. 简述同步方法和同步块&#xff0c;哪个是更好的选…

hydra密码爆破工具详细使用教程

Hydra是一个强大的密码爆破工具&#xff0c;可以用来测试网络系统的弱口令。下面是使用Hydra的基本教程&#xff1a; 1. 安装Hydra 可以从Hydra的官方网站&#xff08;https://github.com/vanhauser-thc/thc-hydra&#xff09;下载最新版本的Hydra&#xff0c;并按照安装说明进…

spring boot 配置监听多端口

如何实现Spring Boot配置监听多端口 1. 概述 在Spring Boot应用中&#xff0c;有时候需要监听多个端口&#xff0c;比如同时监听HTTP和HTTPS端口。本文将介绍如何实现在Spring Boot应用中配置监听多端口。 2. 流程表格 步骤 操作 1 添加依赖 2 创建多端口配置类 3 …