前一阵子在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:show | van-popup的显示 | Boolean | false |
v-model:active | van-picker选中的值 | 单列数据:Object 多列数据:Array |
无 |
label | van-cell左侧标题 | String | 无 |
value | van-cell右侧数据 | String | 无 |
columns | van-picker的数据列表 | Array | 无 |
valueKey | van-picker选项文字对应的键名 | String | text |
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
}
}
结语
本次组件封装时间比较仓促,还有很多没完善的地方,后面会持续优化。如果有问题,欢迎交流指正。