Some time ago in Ve2. X, the Cell, Popup, and Picker based on Vant re-encapsulated a selector component (portal).

Since the vue3.x project was recently started, I took the time to refactor this component with Vue3.0.

encapsulation

<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>
Copy the code

The global call

Register this component globally in main.js, so you don’t have to import it on every page and use it directly on the page where it is needed.

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

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

Using document

Props

parameter instructions type The default value
v-model:show Van – popup displays Boolean false
v-model:active Van-picker Selects the value Single-column data: Object

Multi-column data: Array
There is no
label Van-cell left title String There is no
value Van-cell Data on the right String There is no
columns Van-picker’s list of data Array There is no
valueKey The key name corresponding to the van-picker option text String text

Events

The event name instructions The callback parameter
open Open the van – the popup There is no
select Click van-Picker to select the data Currently selected data

Method of use

Label, value, columns, and valueKey are nothing to say. If you don’t know, consult van-cell and van-Picker’s documentation.

v-model:show

Use V-Model :show to control van-Picker’s presentation.

v-model:active

If you simply choose to bind data after selection, you can directly use the V-Model: Active binding. If you need to do something more complicated, you can use the @select binding method, which returns what the picker selected.

Note that if columns pass in single-column data, the selected object will be returned. If columns pass in multiple columns, an array of objects for each level currently selected is returned.

In the following demo, v-model:active and @select achieve the same effect. Assign the selected value to picker. Active and you can keep v-model:active without using @select.

Demo

<SSPicker
    v-model:active="picker.active"
    v-model:show="picker.show"
    :columns="picker.list"
    :value="picker.active.text? Picker.active. text:' Please select data '"
    label="Data"
    @open="picker.show=true"
    @select="select"
>
</SSPicker>
Copy the code
setup() {
    let picker = ref({
        show: false.active: {},
        // Emulated list data
        list: [{id: 1.text: 1 "test"}, {id: 2.text: "The test 2"}, {id: 3.text: "Test 3",}})let select = (val) = >{
        picker.value.active = val
    }

    return {
        picker,
        select
    }
}
Copy the code

conclusion

The packaging time of this component is relatively short, and there are still many unfinished areas, which will continue to be optimized in the future. If you have any questions, please contact us.