Appearance
DataPicker 数据选择器
增强选择器组件,支持 select、radio、checkbox、cascader 等模式。query 为响应式函数,依赖外部变量变化后自动刷新数据源,轻松实现级联选择场景。通常嵌入 DataForm 中使用。
在线演示
tsx
import { defineComponent, reactive, h } from 'vue'
import DataForm from '@/components/FormLayout'
import type { FormProps } from '@/types/DataFormProps'
export default defineComponent({
name: 'DemoDataPickerFull',
setup() {
const model = reactive({
select: '',
multiple: [],
radio: '',
checkbox: [],
cascader: [],
})
const columns: FormProps['columns'] = [
{
label: '下拉单选',
field: 'select',
type: 'data-picker',
span: 12,
props: {
type: 'select',
query: () =>
Promise.resolve([
{ label: '技术部', value: 'tech' },
{ label: '市场部', value: 'mkt' },
{ label: '财务部', value: 'finance' },
{ label: '人事部', value: 'hr' },
]),
},
},
{
label: '下拉多选',
field: 'multiple',
type: 'data-picker',
span: 12,
props: {
type: 'select',
multiple: true,
query: () =>
Promise.resolve([
{ label: '管理员', value: 'admin' },
{ label: '编辑', value: 'editor' },
{ label: '访客', value: 'guest' },
]),
},
},
{
label: '兴趣分类',
field: 'radio',
type: 'data-picker',
span: 12,
props: {
type: 'radio',
query: () =>
Promise.resolve([
{ label: '运动类', value: 'sport' },
{ label: '文艺类', value: 'art' },
]),
},
},
{
label: '兴趣选项',
field: 'checkbox',
type: 'data-picker',
span: 12,
props: {
type: 'checkbox',
// ⚡ 响应式 query:依赖 radio 的值,切换后自动刷新选项列表
query: () => {
if (model.radio === 'sport') {
return Promise.resolve([
{ label: '篮球', value: 'basketball' },
{ label: '足球', value: 'football' },
{ label: '游泳', value: 'swimming' },
])
}
if (model.radio === 'art') {
return Promise.resolve([
{ label: '音乐', value: 'music' },
{ label: '绘画', value: 'painting' },
{ label: '摄影', value: 'photography' },
])
}
return Promise.resolve([{ label: '请先选择分类', value: '', disabled: true }])
},
},
},
]
return () => (
<div style="display:flex;flex-direction:column;gap:24px;">
<div class="demo-block">
<DataForm model={model} columns={columns} labelWidth={100} />
<div style="margin-top:12px;font-size:13px;color:#666;font-family:monospace;">
当前值:{JSON.stringify(model, null, 2)}
</div>
</div>
</div>
)
},
})亮点:响应式 query
query 函数是响应式的——当它依赖的外部响应式变量发生变化时,选项列表会自动刷新。
ts
const deptId = ref('')
const columns = [
{
label: '岗位',
field: 'post',
type: 'data-picker',
props: {
type: 'select',
// query 内部依赖 deptId.value,当 deptId 变化时自动重新请求
query: () => fetch(`/api/posts?deptId=${deptId.value}`).then(r => r.json()),
},
},
]这个特性在联动场景下非常实用:选择部门后自动刷新岗位列表,无需手动调 refresh() 或额外维护选项状态。
使用方式
在 DataForm 的 columns 中通过 type: 'data-picker' 声明,通过 props.type 指定选择器类型:
ts
{
label: '部门',
field: 'dept',
type: 'data-picker',
props: {
type: 'select', // select | radio | checkbox | cascader
query: () => Promise.resolve([
{ label: '技术部', value: 'tech' },
{ label: '市场部', value: 'mkt' },
]),
},
}Props
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| type | 'select' | 'radio' | 'checkbox' | 'cascader' | 'radio-button' | 'transfer' | 'select' | 选择器类型 |
| query | (searchValue?) => Promise<DataNode[]> | - | 异步加载选项,自动管理 loading |
| options | DataNode[] | - | 静态选项(不异步请求时使用) |
| multiple | boolean | false | 是否多选(select 模式) |
| allowClear | boolean | true | 是否可清除 |
| disabled | boolean | false | 是否禁用 |
| placeholder | string | - | 占位文本 |
| remote | boolean | false | 是否远程搜索 |
| labelKey | string | 'label' | 选项 label 字段名 |
| valueKey | string | 'value' | 选项 value 字段名 |
| childrenKey | string | 'children' | 子选项字段名(cascader) |
| enum | string | - | 字典编码,配合全局配置 dataPicker.enum 使用 |
| labelToModel | string | - | 将选中的 label 同步到 model 的指定字段 |
| fieldsToModel | string[] | - | 将选中项的多个字段同步到 model |
| showAllOption | boolean | false | 是否显示"全部"选项(select 模式) |
| emitPath | boolean | true | cascader 模式是否返回完整路径 |
全局配置
ts
app.use(yoyooUi, {
dataPicker: {
// 字典解析函数:通过 code 返回选项列表
enum: async (code) => {
const res = await axios.get(`/api/enum/${code}`)
return res.data.map((item: any) => ({
label: item.name,
value: item.code,
}))
},
// 自定义类型渲染
typeRender: {
customType: ({ value, notify, props }) => h('span', value),
},
},
})使用 enum 配置后,列配置中只需指定 enum: '字典编码' 即可自动加载选项。