Skip to content

DataPickerTable 表格选择器

基于弹窗表格的选择器组件,点击后弹出 DataTable 供用户选择。支持单选/多选、分页搜索、标签展示、自定义触发等。

在线演示

tsx
import { defineComponent, ref } from 'vue'
import { ElMessage as message } from 'element-plus'
import DataPickerTable from '@/components/DataPickerTable'

export default defineComponent({
  name: 'DemoDataPickerTableFull',
  setup() {
    const single = ref<any>(null)
    const multiple = ref<any[]>([])

    const mockData = Array.from({ length: 30 }, (_, i) => ({
      id: i + 1,
      code: `P${String(i + 1).padStart(4, '0')}`,
      name: `商品${i + 1}`,
      category: ['电子产品', '办公用品', '食品饮料', '家居用品'][i % 4],
      price: +(Math.random() * 10000).toFixed(2),
      stock: Math.floor(Math.random() * 1000),
    }))

    const columns: any[] = [
      { label: '编号', field: 'code', width: 100 },
      { label: '名称', field: 'name', minWidth: 140 },
      { label: '分类', field: 'category', width: 100 },
      { label: '单价', field: 'price', type: 'money', width: 110 },
      { label: '库存', field: 'stock', width: 80 },
    ]

    const query = (params: any) => {
      const { page, pageSize, keyword } = params
      let filtered = mockData
      if (keyword) {
        filtered = mockData.filter((r) => r.name.includes(keyword) || r.code.includes(keyword))
      }
      const start = (page - 1) * pageSize
      return Promise.resolve({
        totalRows: filtered.length,
        rows: filtered.slice(start, start + pageSize),
      })
    }

    return () => (
      <div style="display:flex;flex-direction:column;gap:24px;">
        <div class="demo-block">
          <h4 style="margin:0 0 12px;font-size:15px;">🔘 单选</h4>
          <DataPickerTable
            modelValue={single.value}
            onUpdate:modelValue={(val: any) => (single.value = val)}
            label="选择商品"
            labelKey="name"
            columns={columns}
            query={query}
            searchFields={[
              { label: '关键词', field: 'keyword', type: 'el-input', props: { placeholder: '搜索名称/编号' } },
            ]}
            tableProps={{ height: 320 }}
          />
          <div style="margin-top:8px;font-size:13px;color:#666;font-family:monospace;">
            选中:{JSON.stringify(single.value)}
          </div>
        </div>
        <div class="demo-block">
          <h4 style="margin:0 0 12px;font-size:15px;">🔘 多选(标签模式)</h4>
          <DataPickerTable
            modelValue={multiple.value}
            onUpdate:modelValue={(val: any) => (multiple.value = val)}
            label="选择商品(多选)"
            labelKey="name"
            columns={columns}
            query={query}
            multiple
            mode="tags"
            tableProps={{ height: 320 }}
          />
          <div style="margin-top:8px;font-size:13px;color:#666;font-family:monospace;">
            选中:{JSON.stringify(multiple.value)}
          </div>
        </div>
      </div>
    )
  },
})

Props

属性名类型默认值说明
modelValueany-选中值(v-model)
columnsTableColumn[]-必填。弹窗表格列配置
query(params) => Promise<Result>-必填。弹窗表格数据查询函数
labelstring-触发器前的标签
multiplebooleanfalse是否多选
searchFieldsFormColumn[]-弹窗内的搜索栏字段配置
keywordFieldstring'keyword'搜索时传递关键词的字段名
mode'tags' | 'input''tags'多选展示模式:标签/文本
placeholderstring'请选择'占位文本
allowClearbooleantrue是否可清除
disabledbooleanfalse是否禁用
rowKeystring'id'行唯一标识
labelKeystring'label'显示的 label 字段
valueKeystring'id'绑定的 value 字段
labelToModelstring-将选中项的 label 同步到 model 的指定字段
widthstring | number'100%'触发器宽度
popoverWidthstring | number500弹窗宽度
tablePropsObject-透传 DataTable 的其他属性

示例:在 DataForm 中使用

ts
const columns = [
  {
    label: '关联商品',
    field: 'productId',
    type: 'data-picker-table',
    props: {
      columns: [
        { label: '编号', field: 'code', width: 100 },
        { label: '名称', field: 'name', minWidth: 140 },
        { label: '单价', field: 'price', type: 'money', width: 110 },
      ],
      query: (params) => fetch('/api/products', { body: JSON.stringify(params) }).then(r => r.json()),
      multiple: false,
    },
  },
]