前一阵子在Vue2.x中基于Vant的cell、popup、picker二次封装了一个选择器组件(传送门)。

鉴于最近开始整Vue3.x项目了,于是抽空把这个组件用Vue3.0重构了一遍。

封装

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

<script>

export default {
    name: "SSPicker",
    emits: ["update:show", "update:active", "open", "select"],
    props: {
        show: {
            type: Boolean,
            default: false
        },
        active: [Object, Array],
        label: String,
        value: String,
        columns: Array,
        valueKey: {
            type: String,
            default: "text"
        }
    },
    setup(props, context) {
        let open = () => {
            context.emit("open")
        }

        let close = () => {
            context.emit("update:show", false)
        }

        let confirm = (val) => {
            context.emit("update:active", val)
            context.emit("select", val)
            close()
        }

        return {
            open,
            close,
            confirm
        }
    }
}
</script>

全局调用

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

import SSPicker from "./components/SSPicker/index.vue"
const app = createApp(App)

app.use(vant)
    .use(router)
    .use(store)
    .component("SSPicker", SSPicker)
    .mount("#app")

使用文档

Props

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

Events

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

使用方法

label、value、columns、valueKey没啥好说的,如果不清楚,可以翻阅van-cell和van-picker的文档。

v-model:show

使用v-model:show控制van-picker的展示。

v-model:active

如果单纯的只是选择后绑定数据,可以直接使用v-model:active绑定。如果需要进行其他复杂的操作,可以使用@select绑定方法,该方法返回picker选中的内容。

这边需要注意的是,如果columns传入的是单列数据,选中之后返回的是当前选中的对象。如果columns传入的是多列数据,选中之后返回的是由当前选中每一级的对象组成的数组。

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

Demo

<SSPicker
    v-model:active="picker.active"
    v-model:show="picker.show"
    :columns="picker.list"
    :value="picker.active.text?picker.active.text:'请选择数据'"
    label="数据"
    @open="picker.show=true"
    @select="select"
>
</SSPicker>
setup() {
    let picker = ref({
        show: false,
        active: {},
        // 模拟的列表数据
        list: [
            {
                id: 1,
                text: "测试1",
            },
            {
                id: 2,
                text: "测试2",
            },
            {
                id: 3,
                text: "测试3",
            }
        ]
    })

    let select = (val) =>{
        picker.value.active = val
    }

    return {
        picker,
        select
    }
}

结语

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