您的位置:首页 > 娱乐 > 明星 > uniapp u--input实现select下拉列表 input点击事件

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

2025/2/24 7:42:11 来源:https://blog.csdn.net/weixin_45024453/article/details/141606221  浏览:    关键词:uniapp u--input实现select下拉列表 input点击事件

背景:

技术框架:

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)//查询接口}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com