uniapp组件封装-带有搜索功能Picker

话不多说直接上源码,另外本组件将配合Input直接组合成SelectPicker组件,后续待优化。

1、SelectPicker

2、SinglePicker

<template>
	<!--pickerHospital 子组件-->
	<view class="date-background" v-show="value">
		<view class='date-gray-background' @click="hiddeDatePicker"></view>
		<view class='date-container'>
			<view class="transparent">
				<view class='date-confirm'>
					<view @click="hiddeDatePicker" class="pickerCancel">取消</view>
					<!-- 输入框 -->
					<u-search style="width: 70%;" placeholder="请输入关键字查询" @clear="clearSearch" @change='searchChange'
						:show-action='false' v-model="searchValue" shape="round" clearabled></u-search>
					<view @click="onConfirmClick" class="pickerConfirm">确认</view>
				</view>
				<picker-view :immediate-change='true' indicator-class="indicator" :value="setValues" @change="bindChange"
					mask-style="height:100rpx;"
					style="width: 100%; height: 80%;position:absolute;bottom:0rpx;text-align:center;background:white">
					<picker-view-column class="pickViewColumn">
						<view v-for="item in list" :key="item.id" class="u-column-item" style="height: 68rpx;overflow: hidden;">
							{{item.name}}
						</view>
					</picker-view-column>
				</picker-view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		name: 'SelectPicker',
		props: {
			data: {
				type: Array,
				default () {
					return []
				}
			},
			idField: {
				type: String,
				default(){
					return 'id'
				} 
			},
			labelField: {
				type: String,
				default(){
					return 'label'
				} 
			},
			pickerValues: { //picker默认展示的值
				type: Array,
				default () {
					return [0]
				}
			},
			value: {
				type: Boolean,
				default: false
			}
		},
		data() {
			return {
				searchValue: '', // 搜索值
				setValues: [0], // picker 选择值
				form: { //要传过去的值
					id: '',
					name: ''
				},
				list: [],
				dataSource: []
			}
		},
		created() {
			// console.log('customer-picker-onload')
			// this.initDataSource()
		},
		watch: {
			data: {
				handler(newValue, oldValue) {
					// this.list = newValue
					// console.log(newValue,'mapedCustomer')
					// console.log('getShopCustomers',result)
					//this.dataSource = result.Data
					const ds = newValue.map(item => {
						return {
							...item,
							id: item[this.idField],
							name: item[this.labelField]
						}
					})
					// console.log(ds,'mapedCustomer')
					this.dataSource = ds
					this.list = ds
					console.log(this.list,this.data,this.idField,this.labelField, 'this-list')
				},
				deep: true,
				immediate: true,
			},
			value(newValue, oldValue) {
				this.searchValue = ''
				this.init()
			}
		},
		methods: {
			init() {
				this.$nextTick(() => { //组件渲染完成后在更新数据
					this.setValues = this.pickerValues
				})
			},
			bindChange(e) {
				// console.log(e,'bindChange')
				// let value = e.detail.value.toString();
				// this.dataSource.forEach((item, index) => {
				// 	if (value == index) {
				// 		this.form.id = item.id;
				// 		this.form.name = item.name
				// 	}
				// });
				this.form = this.list[e.detail.value]
				console.log(this.form, 'bindChange')
			},
			hiddeDatePicker() {
				this.$emit('input', false)
			},
			onConfirmClick(e) {
				if (this.form.id === '' && this.list.length > 0) {
					this.form = this.dataSource[0]
				}
				this.hiddeDatePicker()
				this.$emit('select', this.form);
			},
			// 搜索查询
			async searchChange(e) {
				// ,调模糊查询然后 把返回的结果传给this.list数组
				console.log(e, 'searchChange')

				if (e == '') {
					this.list = this.dataSource
				} else {
					let findList = this.dataSource.filter(item => item.name.includes(e))
					this.list = findList
				}
				this.reset()
			},
			reset() { //重置
				this.form = {
					id: '',
					name: ''
				}
				if (this.list.length > 0) {
					this.form = this.list[0]
				}
			},
			clearSearch() { //清空搜索内容
				this.searchValue = ''
				this.list = this.dataSource
			}
		},
	}
</script>

<style lang="scss" scoped>
	.date-background {
		position: fixed;
		left: 0;
		top: 0;
		bottom: 0;
		width: 100%;
		height: 100%;
		z-index: 1111;
	}

	.date-gray-background {
		position: absolute;
		width: 100%;
		top: 0rpx;
		background: rgba(0, 0, 0, .5);
		height: calc(100% - 500rpx);
	}

	.date-container {
		position: absolute;
		width: 100%;
		height: 60%;
		overflow: hidden;
		background: #fff;
		bottom: 0;
		z-index: 1000;
	}

	.date-confirm {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 20rpx;
		font-size: 34rpx;
		line-height: 100rpx;
		z-index: 2;
		// line-height: 70rpx;
		// color: var(--ThemeColor)
	}

	.pickViewColumn {
		height: 60%;
		/* margin-top: -300rpx; */
	}

	.indicator {
		height: 40rpx;
		/* border: 1rpx solid #E5E8E8; */
	}

	.pickerCancel {
		font-size: 30rpx;
		color: #606266;
		// margin-right: 30rpx;
		// padding: 16rpx;
		box-sizing: border-box;
		text-align: center;
		text-decoration: none;

		padding: 0rpx 8rpx;
	}

	.pickerConfirm {
		font-size: 30rpx;
		color: #2979ff;
		// margin-left: 30rpx;
		// padding: 16rpx;
		box-sizing: border-box;
		text-align: center;
		text-decoration: none;
		padding: 0rpx 8rpx;
	}

	.u-column-item {
		display: flex;
		flex-direction: row;
		align-items: center;
		justify-content: center;
		font-size: 30rpx;
		color: #303133;
		padding: 0 8rpx;
	}
</style>

组件使用:

<template>
	<view style="background-color: antiquewhite;">
		选择产品
		<u-button @click="pickShow=true">打开</u-button>
		<u-form-item label="产品">
			<u-input type="select" v-model="selectedValue" border @click="pickShow=true" />
		</u-form-item>
		
		<!-- arrow-down -->
		<!-- <u-field v-model="selectedValue" right-icon="arrow-down-fill" /> -->
		
		<select-picker :data="itemList" v-model="pickShow" :pickerValues="[0]" id-field="ItemCode" label-field="ItemName" @select='onCustomerSelectConfirm' />
	</view>
</template>

<script>
	import SelectPicker from '../../components/SelectPicker/SelectPicker.vue';

	export default {
		components: {
			SelectPicker
		},
		data() {
			return {
				pickShow: false,
				selectedValue:'',
				itemList: [{
					ItemCode: 'A01',
					ItemName: '笔记本'
				}, {
					ItemCode: 'A02',
					ItemName: '笔记本11'
				}, {
					ItemCode: 'A03',
					ItemName: '笔记23本'
				}]
			};
		},
		created() {

		},
		methods: {
			onCustomerSelectConfirm(item) {
				console.log(item,'onSelect-Confirm')
				this.selectedValue = item.ItemName
			}

		},
		onUnload() {
			this.clearSignature();
		},
	};
</script>

<style scoped>
	.mycanvas {
		border: 1px solid gainsboro;
		width: 100%;
	}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值