最近项目中需要在移动端实现一个下拉选择器的功能,UI框架使用的是VantUI,Vant并没有像ElementUI提供现成的下拉选择器,所以这边需要使用vant的cell、popup、picker组件二次封装一个选择器组件。

封装

<template>
    <div class="ss-picker">
        <van-cell
            :title="label"
            :value="value"
            is-link
            @click="open"
        />
        <van-popup
            v-model="show"
            :close-on-click-overlay="false"
            position="bottom"
        >
            <van-picker
                :columns="columns"
                :value-key="valueKey"
                show-toolbar
                @cancel="cancel"
                @confirm="confirm"
            />
        </van-popup>
    </div>
</template>

<script>
export default {
    name: "ssPicker",
    model: {
        prop: "selectValue",
        event: "select"
    },
    props: {
        selectValue: {
            type: Object,
        },
        show: {
            type: Boolean,
            default: false
        },
        label: {
            type: String,
        },
        value: {
            type: String,
        },
        columns: {
            type: Array,
        },
        valueKey: {
            type: String,
            default: "text"
        }
    },
    methods: {
        open() {
            this.$emit("open")
        },
        close() {
            this.$emit("update:show", false)
        },
        // 确认
        confirm(val) {
            this.$emit("select", val)
            this.close()
        },
        // 取消
        cancel() {
            this.close()
        },
    }
}
</script>

全局注册

在main.js全局注册一下此组件,这样就不用每个页面都引入了,直接在需要用的页面使用即可。

import ssPicker from "@/components/ssPicker/index.vue"
Vue.component("ssPicker", ssPicker)

使用文档

Props

参数说明类型默认值
showvan-popup的显示Booleanfalse
labelvan-cell左侧标题String
valuevan-cell右侧数据String
columnsvan-picker的数据列表Array
valueKeyvan-picker选项文字对应的键名Stringtext

Events

事件名说明回调参数
open打开van-popup
select点击van-picker选中数据当前选中行数据

使用方法

如果单纯的只是选择后绑定数据,可以直接使用v-model绑定。

如果需要进行其他复杂的操作,可以使用@select绑定方法,该方法返回picker选中的内容。

下面demo中v-model@select实现的效果都是一样的,给this.picker.active赋上选中的值,可以只保留v-model,不需要再用@select。

Demo

<ssPicker
    v-model="picker.active"
    :columns="picker.list"
    :show.sync="picker.show"
    :value="picker.active.text?picker.active.text:'请选择测试内容'"
    valueKey="text"
    label="测试内容"
    @open="picker.show=true"
    @select="selectPicker"
>
</ssPicker>
export default {
    data() {
        return {
            // 选择器
            picker: {
                show: false,
                active: {},
                list: []
            },
        }
    },
    methods: {
        selectPicker(val){
            this.picker.active = val
        }
    }
}

结语

本次组件封装时间比较仓促,还有很多没完善的地方,后面找时间再优化一下吧。如果有问题,欢迎交流指正。