Skip to content

DataPicker 数据选择器

增强选择器组件,支持 selectradiocheckboxcascader 等模式。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
optionsDataNode[]-静态选项(不异步请求时使用)
multiplebooleanfalse是否多选(select 模式)
allowClearbooleantrue是否可清除
disabledbooleanfalse是否禁用
placeholderstring-占位文本
remotebooleanfalse是否远程搜索
labelKeystring'label'选项 label 字段名
valueKeystring'value'选项 value 字段名
childrenKeystring'children'子选项字段名(cascader)
enumstring-字典编码,配合全局配置 dataPicker.enum 使用
labelToModelstring-将选中的 label 同步到 model 的指定字段
fieldsToModelstring[]-将选中项的多个字段同步到 model
showAllOptionbooleanfalse是否显示"全部"选项(select 模式)
emitPathbooleantruecascader 模式是否返回完整路径

全局配置

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: '字典编码' 即可自动加载选项。