基于vant-ui的vant-picker二次封装
文章目录
前言
在项目中表单项经常会出现下拉选择框,但是在vant中没有提供直接的select组件,但是可以使用Field、Popup和Picker这三个组件组合来完成。
如果页面中只有一个select这样做做也还可以,但是页面中出现多个select就有点繁琐了,所以本文进行组件的封装。
本文主要介绍了不封装选择框的用法和封装组件后的用法,通过对比可以看出封装后代码简洁性。
一、vant提供的组件用法
1.代码片段
mfCusPersonJobInsert.vue
<template>
<div>
<van-field
readonly
clickable
:value="mfCusCustomer.idTypeName"
label="证件类型"
placeholder="请选择证件类型"
@click="idTypeshow = true"
input-align="right"
>
</van-field>
<!-- 证件类型选择器 -->
<van-popup v-model="idTypeshow" position="bottom">
<van-picker
show-toolbar
:columns="idTypecolumn"
@cancel="idTypeshow = false"
@confirm="onConfirm"
/>
</van-popup>
</div>
</template>
<script>
import dictionary from '@/utils/dictionary'
export default {
name:'mfCusPersonJobInsert',
//import引入的组件需要注入到对象中才能使用
components: {},
props: {
},
data() {
//这里存放数据
return {
mfCusCustomer:{
},//客户实体
idTypecolumn: dictionary.dictionary.idType,
idTypeshow: false,
};
},
//监听属性 类似于data概念
computed: {},
//监控data中的数据变化
watch: {},
//方法集合
methods: {
//证件类型
onConfirm(idType) {
this.mfCusCustomer.idTypeName = idType.text;
this.mfCusCustomer.idTypeId = idType.keyId;
this.idTypeshow = false; //此属性关闭下拉框组件的弹层
},
},
//生命周期 - 创建完成(可以访问当前this实例)
created() {
},
//生命周期 - 挂载完成(可以访问DOM元素)
mounted() {
},
beforeCreate() {}, //生命周期 - 创建之前
beforeMount() {}, //生命周期 - 挂载之前
beforeUpdate() {}, //生命周期 - 更新之前
updated() {}, //生命周期 - 更新之后
beforeDestroy() {}, //生命周期 - 销毁之前
destroyed() {}, //生命周期 - 销毁完成
activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
}
</script>
<style lang='scss'>
</style>
2.下拉框数据源
dictionary.js
export default{
dictionary:{
idType:[
{text:"身份证",keyId:"0"},
{text:"护照",keyId:"2"},
{text:"军官证",keyId:"3"},
{text:"港澳居民来往内地通行证",keyId:"5"},
{text:"其他",keyId:"10"}
],
}
}
3.实现效果
二、封装组件
1.引入vant库
import Vant from 'vant'
Vue.use(Vant);
2.组件实现
<template>
<div>
<!-- select选择框文本对应的id -->
<van-field
v-model="nameId"
:name="$attrs.nameId"
type="hidden"
v-show="false"
/>
<!-- select选择框文本 -->
<van-field
v-model="result"
v-bind="$attrs"
readonly
:name="name"
@click="show = !show"
>
<template #right-icon>
<van-icon class="iconfont" class-prefix="icon" name="xiala" size="18" color="#CCCCCCC"/>
</template>
</van-field>
<van-popup v-model="show" position="bottom">
<van-picker
:columns="columns"
show-toolbar
:title="$attrs.label"
@cancel="show = !show"
@confirm="onConfirm"
/>
</van-popup>
</div>
</template>
<script>
export default {
name:'VantFieldSelect',
model: {
prop: "selectValue"
},
props: {
columns: {
type: Array
},
selectValue: {
type: String
},
name:{
type: String //父组件传进来一个name
}
},
data() {
return {
show: false,
result: this.selectValue,
nameId:''
};
},
methods: {
onConfirm(value) {
//value.text value.keyId
this.result = value.text;
this.nameId = value.keyId;
this.show = !this.show;
this.$emit("getMessage", this.name,value.keyId);//把value值传给父组件
},
},
watch: {
selectValue: function(newVal) {
this.result = newVal;
},
result(newVal) {
this.$emit("input", newVal);
}
}
};
</script>
<style></style>
3.组件调用
mfCusPersBaseInfoInsert.vue
<template>
<div>
<van-form validate-first @submit="onSubmit">
<!-- 证件类型 -->
<vant-field-select
label="证件类型"
name='idTypeText'
nameId="idType"
placeholder="请选择"
v-model="formData.idTypeText"
:columns="idTypecolumn"
@getMessage="setSelectValue"
:rules="[{ validator, message: '请输入正确内容' }]"
/>
<div style="margin: 16px;">
<van-button round block type="info" native-type="submit">提交</van-button>
</div>
</van-form>
</div>
</template>
<script>
import dictionary from '@/utils/dictionary'
import VantFieldSelect from '@/components/VantFieldSelect'
export default {
name:'mfCusPersBaseInfoInsert',
//import引入的组件需要注入到对象中才能使用
components: {
VantFieldSelect,
},
props: {
},
data() {
//这里存放数据
return {
formData:{
idTypeText:'',
idType:"",
},//客户实体
idTypecolumn: dictionary.dictionary.idType,
};
},
//监听属性 类似于data概念
computed: {},
//监控data中的数据变化
watch: {},
//方法集合
methods: {
setSelectValue(name,value){
let a=name.split("Text")[0];
this.formData[a]=value;
// document.getElementById(name).value=value;
},
onSubmit(values) {
debugger
this.formData;
console.log('submit', values);
},
},
//生命周期 - 创建完成(可以访问当前this实例)
created() {
},
//生命周期 - 挂载完成(可以访问DOM元素)
mounted() {
},
beforeCreate() {}, //生命周期 - 创建之前
beforeMount() {}, //生命周期 - 挂载之前
beforeUpdate() {}, //生命周期 - 更新之前
updated() {}, //生命周期 - 更新之后
beforeDestroy() {}, //生命周期 - 销毁之前
destroyed() {}, //生命周期 - 销毁完成
activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
}
</script>
<style lang='scss'>
</style>
4.组件效果
5.表单提交时获取下拉框文本和下拉框文本对应的key值
6.自定义formData中下拉框文本和下拉框文本对应的key值
总结
实际应用中需要拿到下拉选择的id值,组件封装中又添加了一个van-field,用于存储下拉框id的值,同时在表单提交中和data中也可以拿到下拉框文本和id,这样就完没解决了代码的复用。