123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- import { getCurrentInstance, h, ref, defineComponent } from 'vue'
- import { ElTable, ElTableColumn, ElRadio } from 'element-plus'
- import { getFieldValue, isNotEmpty, isEmpty, isArray } from '@cip/utils/util'
- // import { handleFormConfig, handleTableConfig } from '../helper/d-render'
- import CipFormItem from '@cip/components/cip-form-item'
- import CipTableHandler from '@cip/components/cip-table-handler'
- import './index.less'
- // import { getViewComponent } from '@cip/components/cip-form-input/util'
- // import { useFieldValue } from '@cip/components/cip-form-item/form-item-hooks'
- export default defineComponent({
- name: 'CipTable',
- inheritAttrs: false,
- props: {
- offset: Number,
- height: {
- type: String
- },
- selectable: {
- type: Function
- },
- selectRadio: {
- type: [String, Number]
- },
- selectLabel: {
- type: String
- },
- selectType: {
- type: String
- },
- selectColumns: Array,
- columns: { type: Array, default: () => [] },
- fieldKey: String,
- tableHeaderLabel: String,
- data: {
- type: Array,
- default: () => []
- },
- dependOnValues: Object, // 作为basic-table组件时对外部的依赖
- inForm: Boolean, // 是否为表单的输入或展示
- rowKey: [String, Function],
- treeProps: {
- type: Object,
- default: () => ({})
- },
- handlerWidth: {
- type: String,
- default: '120px'
- },
- withTableHandle: Boolean,
- hideIndex: Boolean,
- indexFixed: Boolean // 左侧悬浮
- },
- emits: ['sort', 'update:data', 'update:selectColumns'],
- setup (props, context) {
- const instance = getCurrentInstance()
- const cipTableRef = ref()
- instance.ctx.cipTableRef = cipTableRef
- const updateData = (val, index) => {
- console.log('updateData')
- const data = props.data
- data[index] = val
- context.emit('update:data', data)
- }
- const getFormItem = (key, config, row, index) => {
- return h(CipFormItem, {
- key: index,
- model: row,
- fieldKey: key,
- config: config,
- inTable: true,
- tableDependOnValues: props.dependOnValues,
- tableData: props.data,
- 'onUpdate:model': (val) => {
- row = val
- updateData(val, index)
- }
- })
- }
- const tableColumn = ({ key, config } = {}) => {
- const headerSlots = ({ column, $index }) => {
- return <span>
- {config.required === true && <span class={['cip-danger-color']} style={{ marginRight: '4px' }}>*</span>}
- {config.label}
- </span>
- }
- const { children, ...tableColumnConfig } = config
- return h(ElTableColumn, {
- prop: key,
- align: config.type === 'number' ? 'right' : '', // 针对数字类型进行居右优化
- style: 'display: flex;',
- ...tableColumnConfig
- }, {
- header: headerSlots,
- default: ({ row, $index, column }) => {
- // if ($index === -1) return // 如果写上这个代码 children 将失效
- // const otherValue = !isEmpty(config.otherKey) ? getFieldValue(row, config.otherKey) : undefined
- if (isArray(config.children) && config.children.length > 0) {
- return config.children.map(tableColumn)
- } else {
- if ($index < 0) return null
- const modelValue = getFieldValue(row, key)
- // const [otherValue] = useFieldValue({ value: config.otherKey }, { value: row }, () => {})
- // 同时开放key值插槽及key+'Slot' 的插槽
- if (!['default', 'append', 'expand', '_handler'].includes(key) && context.slots[key]) {
- return context.slots[key]({ row, $index, column })
- }
- // 特殊字段插槽 ['default', 'append']
- if (context.slots[`${key}Slot`]) {
- return context.slots[key]({ row, $index, column })
- }
- const inputConfig = { ...config } // 进行一次浅拷贝
- inputConfig.width = '100%'
- inputConfig.hideLabel = true
- // config.labelWidth = 0
- if (inputConfig.writable === true) {
- // 将form 输入组件的宽度设为100% config中的width 代表表格宽度
- inputConfig.ruleKey = `${props.fieldKey}.${$index}.${key}`
- return getFormItem(key, inputConfig, row, $index)
- }
- if (!inputConfig.writable) {
- // if ((config.dependOn?.length > 0 || config.outDependOn?.length > 0)) {
- // 开启响应的效果 开启只读模式
- inputConfig.readable = true
- if (!inputConfig.dynamic) {
- inputConfig.dependOn = []
- }
- // ERROR: 此处将导致watch 出现错误
- return getFormItem(key, inputConfig, row, $index)
- // } else {
- // // TODO: 考虑是否合并, 合并后样式是否有异常
- // const viewProps = {
- // modelValue,
- // model: row,
- // config: config,
- // otherValue: otherValue.value
- // }
- // // 存在otherKey的时候把otherKey的值赋给otherValue
- // return h(getViewComponent(config.type), viewProps)
- // }
- } else {
- return modelValue
- }
- }
- }
- })
- }
- const tableColumns = () => props.columns.map(tableColumn)
- const tableDefaultSlots = () => {
- const slots = tableColumns()
- if (isNotEmpty(props.offset) && props.offset > -1 && !props.hideIndex) {
- const indexColumn = h(ElTableColumn, { label: '序号', fixed: props.indexFixed ? 'left' : '', width: isEmpty(props.rowKey) ? '55px' : '75px' }, {
- default: ({ $index }) => `${$index + 1 + props.offset}`
- })
- slots.unshift(indexColumn)
- }
- if (props.selectType === 'checkbox') {
- const option = { type: 'selection', width: '45px', fixed: 'left' }
- if (isNotEmpty(props.selectable)) { // 选择
- option.selectable = (row, index) => props.selectable(row || {}, index)
- }
- const selectionColumn = h(ElTableColumn, option)
- slots.unshift(selectionColumn)
- }
- if (props.selectType === 'radio') {
- const selectionColumn = h(ElTableColumn, { width: '45px', fixed: 'left' }, {
- default: ({ row }) => h(ElRadio, {
- label: row[props.selectLabel] ?? row.id,
- modelValue: props.selectRadio
- }, { default: () => '' })
- })
- slots.unshift(selectionColumn)
- }
- if (context.slots.expand) {
- const expendColumn = h(ElTableColumn, { type: 'expand', width: '32px' }, {
- default: ({ row, index }) => context.slots.expand({ row, index })
- })
- slots.unshift(expendColumn)
- }
- // jsx编译时有时候会去除_handler插槽
- if (props.withTableHandle && (context.slots._handler || context.slots.$handler)) {
- const handlerSlot = context.slots._handler || context.slots.$handler
- const handlerColumn = h(ElTableColumn, { label: '操作', fixed: 'right', width: props.handlerWidth || '120px' }, {
- default: ({ row, $index }) => h(CipTableHandler, { limit: 3 }, {
- default: () => handlerSlot({ row, $index })
- })
- })
- slots.unshift(handlerColumn)
- // 内部组件必须使用cip-table-button
- }
- if (context.slots.default) {
- slots.push(context.slots.default())
- }
- if (context.slots.prepend) {
- const prependSlots = context.slots.prepend()
- if (isArray(prependSlots)) {
- slots.unshift(...prependSlots)
- } else {
- slots.unshift(prependSlots)
- }
- }
- if (context.slots.append) {
- const appendSlots = context.slots.append()
- if (isArray(appendSlots)) {
- slots.push(...appendSlots)
- } else {
- slots.push(appendSlots)
- }
- }
- if (props.tableHeaderLabel) return h(ElTableColumn, { label: props.tableHeaderLabel, align: 'center' }, { default: () => slots })
- return slots
- }
- const onSortChange = ({ prop, order }) => {
- context.emit('sort', { prop, order })
- }
- return () => h(ElTable, {
- ...context.attrs,
- data: props.data,
- ref: cipTableRef,
- height: props.height,
- class: 'cip-table',
- rowKey: props.rowKey,
- treeProps: props.treeProps,
- onSortChange,
- onSelectionChange: (val) => {
- context.emit('update:selectColumns', val)
- }
- }, {
- default: tableDefaultSlots
- })
- }
- })
|