增强uni-app的uni-picker-view组件(添加搜索和禁选功能)

本文介绍了如何在uni-app中增强uni-picker-view组件,增加了搜索和禁选功能。通过组件文件的修改和配置,实现了用户在选择列表中能够进行搜索过滤,并能对特定选项进行禁用,提升用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、组件文件如下:
 

<template>
	<view>
		<view>
			<!-- 普通弹窗 -->
			<uni-popup ref="popup" background-color="#fff" @change="change">
				<view>
					<view>
						<uni-row>
						    <uni-col :span="6">
								<button plain="true" style="margin-top: 20rpx;border-style:none;" @click="cancelChange()"><text class="button-text">取消</text></button>
						    </uni-col>
						    <uni-col :span="12">
						        <uni-search-bar style="margin-top: 15rpx;font-size: 3em;" :value="searchKey" radius="0" placeholder="搜索" clearButton="none" cancelButton="none" @input="search"/>
						    </uni-col>
							<uni-col :span="6">
								<button plain="true" style="margin-top: 20rpx;border-style:none;" @click="sureSelect()"><text class="button-text">确定</text></button>
							</uni-col>
						</uni-row>
						<picker-view v-if="visible" :value="pickerValue" indicator-style="height:50px;" @change="bindChange">
							<picker-view-column>
								<view class="item" v-for="(item,index) in pickerList" :key="index">{{item}}</view>
							</picker-view-column>
						</picker-view>
					</view>
				</view>
			</uni-popup>
		</view>
	</view>
</template>

<script>
	export default {
		props:{
			value:String //确认选择值
			,list:Array //数据列表
			,disableKey:String//禁用关键词
			,disableTips:String//禁用提示
		}
		,watch:{
			value() {
				this.$emit('input',this.value);
			}
			,list(){
				this.init()
			}
			,disableKey(){
				this.defaultVal.picker.disableKey=this.disableKey
			}
			,disableTips(){
				this.defaultVal.picker.disableTips=this.disableTips
			}
			,immediate: true
		}
		,data() {
			const defaultVal= //默认常量
			{
				global:{
					debug:true
					,title:'my-picker-view'
				}
				,show:{
					value:'未选择'
				}
				,search:{
					searchKey:''
				}
				,picker:{
					pickerValue:[0]
					,visible:true
					,pickerList:[]
					,isChoose:false
					,chooseVal:''
					,disableKey:'已'
					,disableTips:'该选择项已在不可选状态,请重新选择!'
				}
			}
			return {
				defaultVal
				,title: ''
				,debug:true
				,pickerValue:[]
				,visible: true
				,pickerList:[]
				,searchKey:''
				,isChoose:true
				,chooseVal:''
			}
		}
		,mounted() {//初始化
			this.init()
		}
		,methods: {
			change(e) {
				// console.log('当前模式:' + e.type + ',状态:' + e.show);
				if(e.type=='center'&&e.show==false){
					this.resetSearch()
				}
			}
			,toggle(type) {
				// open 方法传入参数 等同在 uni-popup 组件上绑定 type属性
				this.$refs.popup.open(type)
			}
			,sureSelect(){
				this.debuglog('this.defaultVal.picker.disableKey')
				if(this.chooseVal.toString().indexOf(this.disableKey)>0){
					//弹窗提示:无法选取已代理区域
					uni.showToast({
					    title: this.disableTips,
					    duration: 2000
					});
				}else{
					this.value=this.chooseVal
					this.$refs.popup.close()
					this.resetSearch()
				}
			}
			,cancelChange(){
				this.$refs.popup.close()
				this.resetSearch()
			}
			,requestList(){//请求列表数据
				this.defaultVal.show.value=this.value
				this.defaultVal.picker.pickerList=this.list
				this.defaultVal.picker.pickerValue=[this.defaultVal.picker.pickerList.length-1]
				this.defaultVal.picker.chooseVal=this.defaultVal.picker.pickerList[this.defaultVal.picker.pickerValue[0]]
				this.defaultVal.picker.disableKey=this.disableKey
				this.defaultVal.picker.disableKey=this.disableTips
			}
			,resetAll(){//重置或初始化默认设置
				//初始化初始值
				this.debug=this.deepCopy(this.defaultVal.global.debug)
				this.title=this.deepCopy(this.defaultVal.global.title)
				this.searchKey=this.deepCopy(this.defaultVal.search.searchKey)
				this.pickerList=this.deepCopy(this.defaultVal.picker.pickerList)
				this.asc=this.deepCopy(this.defaultVal.picker.asc)
				this.visible=this.deepCopy(this.defaultVal.picker.visible)
				this.pickerValue= this.deepCopy(this.defaultVal.picker.pickerValue)
				this.isChoose=this.deepCopy(this.defaultVal.picker.isChoose)
				this.chooseVal=this.deepCopy(this.defaultVal.picker.chooseVal)
			}
			,init(){
				this.requestList()
				this.resetAll()
			}
			,bindChange(e){
				this.chooseVal=this.pickerList[e.detail.value[0]]
			}
			,search(e){
				this.searchKey=e
				if(this.searchKey==''){
					this.resetSearch()
				}else{
					this.pickerList.splice(0,this.pickerList.length)
					this.debuglog('this.searchKey')
					this.debuglog('this.defaultVal.picker.pickerList')
					for(let i=0;i<=this.defaultVal.picker.pickerList.length-1;i++){
						let searchVal=this.defaultVal.picker.pickerList[i].toString()
						if(searchVal.indexOf(this.searchKey)!=-1)
						{
							this.pickerList.push(searchVal)
						}
					}
					this.pickerValue=[this.pickerList.length-1]
					this.chooseVal=this.pickerList[this.pickerValue[0]]
				}
			}
			,resetSearch(){
				this.searchKey=''
				this.pickerList.splice(0,this.pickerList.length)
				this.pickerList= this.deepCopy(this.defaultVal.picker.pickerList);
				this.pickerValue=[this.pickerList.length-1]
				this.chooseVal=this.pickerList[this.pickerValue[0]]
			}
			,debuglog(obj,open){
				if(open==true||open==undefined){
					if(this.debug){
						console.log('debug调试中,检测的对象'+obj+'内容为'+JSON.stringify(eval(obj)))
					}
				}
			}
			,deepCopy(obj) 
			{
				// 判断如果不是引用类型,直接返回数据即可
				if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || typeof obj === 'undefined' || !obj) 
				{
					return obj
				}  
				return JSON.parse(JSON.stringify(obj));
			}
		}
	}
</script>

<style>
    picker-view {
        width: 100%;
        height: 600rpx;
        margin-top:20rpx;
    }

    .item {
        line-height: 100rpx;
        text-align: center;
    }
</style>

2、演示实例如下:
 

<template>
	<view>
		<view>当前选取确认值:{{selectVal}}</view>
		<button @click="changeList()">更换列表</button>
		<button class="button" type="primary" @click="openMpv()"><text class="button-text">打开选择器</text></button>
		<mpv ref='mpv' v-model="selectVal" :list="list" :disableKey="disableKey" :disableTips="disableTips"></mpv>
	</view>
</template>

<script>
	import mpv from '../../picker-view/my-picker-view/my-picker-view.vue'
	export default {
		components:{
			mpv
		}
		,data() {
			return {
				selectVal:'请选择'
				,aa:[['苹果(售罄)','香蕉','菠萝(售罄)','橘子'],['apple(sellof)','banana','boluo','orange']]
				,list:['苹果(售罄)','香蕉','菠萝(售罄)','橘子'] //数据列表
				,disableKey:'售罄'//禁用关键词
				,disableTips:'抱歉,此水果已售罄,请重新选择!'//禁用提示
			}
		}
		,methods: {
			changeList(){
				if(this.list[0]==this.aa[0][0]){
					this.list=this.aa[1]
					this.disableKey='sellof'
				}else{
					this.list=this.aa[0]
					this.disableKey='售罄'
				}
			}
			,openMpv(){
				this.$refs.mpv.toggle('bottom')
			}
		}
	}
</script>

<style>

</style>

3、界面截图如下:

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值