基于vant-ui的vant-picker二次封装

基于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.实现效果

基于vant-ui的vant-picker二次封装

二、封装组件

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.组件效果

基于vant-ui的vant-picker二次封装

5.表单提交时获取下拉框文本和下拉框文本对应的key值

基于vant-ui的vant-picker二次封装

6.自定义formData中下拉框文本和下拉框文本对应的key值

基于vant-ui的vant-picker二次封装

总结

实际应用中需要拿到下拉选择的id值,组件封装中又添加了一个van-field,用于存储下拉框id的值,同时在表单提交中和data中也可以拿到下拉框文本和id,这样就完没解决了代码的复用。

上一篇:初始化一个vant H5项目


下一篇:图数据库 Nebula Graph 的安装部署