一 最终效果
二、参数配置
1、代码示例:
<t-select
v-model="formData.materialNo"
valueKey="materialNo"
showLabel="materialName"
labelKey="label"
label="判定品级"
input-align="right"
placeholder="请选择判定品级"
right-icon="arrow"
:list="judgingMaterialList"
/>
2、配置参数(t-select Attributes)继承van-field和van-picker的属性
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
v-model | 选中的valueKey值,页面展示是:showLabell | String | - |
list | 下拉数据源 | Array | - |
valueKey | 下拉选择传给后台的key | String | key |
labelKey | 下拉选择显示label | String | label |
isSearch | 是否显示搜索框 | Boolean | false |
showLabel | van-field显示的文本 | String | - |
searchPlaceholder | 搜索提示语 | String | 请输入搜索内容 |
3、events 事件
事件名 | 说明 | 返回值 |
---|---|---|
emitVal | 点击确定按钮时触发 | 选中的对象 |
三、源码
<template>
<div class="t-select">
<van-field v-bind="fieldAttrs" :value="text" @click="clickField" />
<van-popup v-model="isShow" position="bottom">
<van-field
v-model="searchVal"
:placeholder="searchPlaceholder"
@input="search"
v-if="isSearch"
clearable
input-align="left"
/>
<van-picker
v-on="$listeners"
v-bind="$attrs"
ref="picker"
@change="changeVal"
:value-key="labelKey"
:columns="columnsData"
show-toolbar
@confirm="onConfirm"
@cancel="isShow = false"
/>
</van-popup>
</div>
</template>
<script>
export default {
name: 'TSelect',
props: {
// 下拉数据源
list: {
type: Array,
default: () => []
},
val: { default: null },
// 下拉选择传给后台的key
valueKey: {
type: String,
default: 'key',
},
// 下拉选择显示label
labelKey: {
type: String,
default: 'label',
},
// 是否显示搜索框
isSearch: {
type: Boolean,
default: false
},
// van-field显示的文本
showLabel: {
type: String
},
searchPlaceholder: {
type: String,
default: '请输入搜索内容'
}
},
model: {
prop: 'val',
event: 'emitVal'
},
data() {
return {
isShow: false,
columnsData: this.list,
searchVal: '',
text: '',
}
},
watch: {
val: {
handler(newVal) {
// 赋值回显
if (newVal) {
const findItem = this.list.find((item) => item[this.valueKey] == newVal)
this.text = findItem[this.showLabel || this.labelKey]
}
},
deep: true,
immediate: true
},
list: {
handler(newVal) {
this.columnsData = newVal
},
deep: true,
immediate: true
}
},
computed: {
fieldAttrs() {
return {
readonly: true,
clickable: true,
...this.$attrs
}
}
},
methods: {
clickField() {
this.isShow = true
this.$emit('clickField', true)
},
onConfirm(value) {
// console.log('点击确定', value)
this.$emit('emitVal', value[this.valueKey], value)
this.text = value[this.showLabel || this.labelKey]
this.isShow = false
},
changeVal() {
this.$emit('change')
},
clear() {
this.text = ''
this.$emit('emitVal', null)
},
// 搜索
search(val) {
// console.log('搜索', val)
if (val) {
this.columnsData = this.columnsData.filter(item => {
return item[this.labelKey].indexOf(val) > -1
})
} else {
this.columnsData = JSON.parse(JSON.stringify(this.list))
}
},
}
}
</script>
相关文章
基于ElementUi再次封装基础组件文档
基于ant-design-vue再次封装基础组件文档
vue3+ts基于Element-plus再次封装基础组件文档