前言
对于选择器组件,vant 中的 picker 组件是一个非常合适的选择。它不仅提供了灵活的配置选项,还可以很方便地与其他 vant 组件结合使用,帮助我们快速搭建出漂亮、易用的移动端页面。在本文中,我将为大家介绍如何基于 vant 的 picker 组件进行二次封装,以便更好地满足实际的业务需求。
实现思路
- 首先定义一个子组件页面用来封装选择器;
- 在父组件中(使用的页面)引入封装组件(子组件)并注册,然后在页面中使用,在父组件中给标签(注册的组件名)上绑定多个属性, 属性上挂载需要传递的值,通过
props
在子组件(封装文件)接收数据; - 在子组件中自定义确定的事件,调用这个事件后,子组件通过
this.$emit('自定义事件名',要传递的数据)
发送父组件可以监听的数据,最后父组件监听子组件事件,调用事件并接收传递过来的数据。
定义的参数
参数 | 描述 |
---|---|
selectValue | 绑定值 model |
keyValue | 绑定的 key 字段 |
keyLabel | 绑定的 value 字段 |
columns | 绑定的 option 数据源 |
required | 是否显示红色 * 校验 |
rules | 校验规则 |
required | 是否必填 |
confirm | 选中的回调函数 |
封装文件
<template><div><van-field v-model="textValue" v-bind="$attrs" :name="$attrs.name" :rules="rules" :required="required" :readonly="readonly":is-link="islink" @click="show = !show" /><van-popup v-model="show" get-container="body" position="bottom"><van-picker :columns="columns" show-toolbar :value-key="keyValue" :title="$attrs.label" @cancel="show = !show" @confirm="onConfirm"><template #option="option">{{ option[keyLabel] }}</template></van-picker></van-popup></div>
</template><script>
export default {props: {required: {type: Boolean,},readonly: {type: Boolean,},islink: {type: Boolean,},columns: {type: Array,},rules: {type: Array,},selectValue: {type: String,},keyValue: {type: String,},keyLabel: {type: String,},},data() {return {show: false,textValue: "",selectOptions: [],};},methods: {onConfirm(obj) {this.textValue = obj.label;this.show = !this.show;this.$emit("confirm", obj);},formatterValue(value) {let str = "";if (!this.columns.length || !value.length) {str = "";} else {let oArr = this.columns.filter((item) => {return item[this.keyValue].toString() == value.toString();});str = oArr[0][this.keyLabel];}return str;},//根据key值格式化成picker需要的option格式formatColumnsByKey() {let arr = [];let value = this.keyValue ? this.keyValue : "value";let label = this.keyLabel ? this.keyLabel : "label";this.columns.map((item) => {arr.push({label: item[label],value: item[value],});});this.selectOptions = arr;},},watch: {columns: {handler(newValue) {this.textValue = this.formatterValue(this.selectValue ? this.selectValue : "");},deep: true,immediate: true,},selectValue: {handler(newValue) {this.textValue = this.formatterValue(newValue ? newValue : "");},deep: true,immediate: true,},},
};
</script>
使用文件
<template><div><van-form validate-first><VanSelect name="qylx" label="企业类型" placeholder="请选择企业类型" :selectValue="qylx" :keyValue="`value`" :keyLabel="`label`" :required="true":readonly="true" :columns="qylxOption" :rules="rules.qybh" @confirm="qylxConfirm" /><div class="btnBomBox"><van-button round size="small" block @click="submitOn" type="info">提交</van-button></div></van-form></div>
</template><script>
import VanSelect from "@/components/vanSelect/index";
export default {components: {VanSelect,},data() {return {qylx: "",qylxOption: [{ label: "自营企业", value: "1" },{ label: "其他企业", value: "2" },],rules: {qybh: [{required: true,message: "请选择企业类型",},],},};},methods: {// 点击确定qylxConfirm(value) {this.qylx = value.value;},// 提交submitOn() {console.log(this.qylx);},},
};
</script><style scoped>
.btnBomBox {padding: 0px 16px;display: flex;justify-content: center;
}
</style>