记录遇到的一个奇怪问题。
在用el-table的时候,有时候表头是不固定的,还可能存在多级表头的情况,所以写了一个判断,有children的时候就迭代显示el-table-column,结果在没有子级的时候可以正常显示,在有子级的时候子级表头就显示不出来,但是加了下面这个,或者在这个地方随便放点东西(比如放几个字,如:“askdjh”)就能正常显示了,好奇怪。。。
<div>不加这个子表头显示不出来。。。</div>
<template>
<el-table-column
v-for="field in fields"
:key="field"
:prop="field[fieldProp.prop]"
:label="field[fieldProp.label]"
:min-width="field.minWidth ? field.minWidth : 200"
show-overflow-tooltip
align="center"
>
<!-- 显示字典 -->
<template #default="scope" v-if="field.options && field.optionKey">
<dict-tag :options="field.options" :value="scope.row[field.optionKey]" />
</template>
<template v-if="field.children && Array.isArray(field.children)">
<div>不加这个子表头显示不出来。。。</div>
<!-- askdjh-->
<custom-table-column :fields="field.children" :fieldProp="fieldProp"></custom-table-column>
</template>
</el-table-column>
</template>
<script lang="ts" setup name="CustomTableColumn">
import { IField, IFieldProp } from '../../ts/mixin'
const props = defineProps({
fields: {
//字段
type: Array as PropType<IField[]>,
},
fieldProp: {
//字段显示和使用的值
type: Object as PropType<IFieldProp>,
default: () => {
return {
prop: 'name',
label: 'nickname',
}
},
},
})
</script>
// mixin.ts文件
// 字段
export interface IField {
name?: string //名称
nickname?: string //中文label
prop?: string //名称
label?: string //中文label
htmlType?: string
minWidth?: number //该列的宽度
options?: any //该列的字典类型或可选值
optionKey?: string // 字典对应的键值
children?: IField[]
}
// 字段使用的key值
export interface IFieldProp {
prop: string // 用什么值
label: string // 值的名称
}
补充————————————————————————(假装分割线)————————————————————————
重新完善了一下:
之前写的还不够自动,因为遇到需要把那列显示成按钮或者其他元素的,就需要添加一个列,而不能根据字段信息显示出来,所以重新优化了一下。而且现在不用加那段乱七八糟的也可以正常显示了。
这样就可以根据field里面的renderH函数来控制每一个字段的显示和操作了。
重点在render、h函数和component-render.vue文件里面。
<template>
<el-table-column
v-for="field in fields"
:key="field.name"
:prop="field[fieldProp.prop]"
:label="field[fieldProp.label]"
:min-width="field.minWidth ? field.minWidth : 200"
show-overflow-tooltip
:align="field.align || 'center'"
>
<template #default="scope" v-else-if="field.renderH">
<componentRender :opt="field" :data="scope.row" />
</template>
<template v-if="field.children && Array.isArray(field.children)">
<custom-table-column :fields="field.children" :fieldProp="fieldProp"></custom-table-column>
</template>
</el-table-column>
</template>
<script lang="ts" setup name="CustomTableColumn">
import { IField, IFieldProp } from '../../ts/mixin'
import componentRender from './component-render.vue'
const props = defineProps({
fields: {
//字段
type: Array as PropType<IField[]>,
},
fieldProp: {
//字段显示和使用的值
type: Object as PropType<IFieldProp>,
default: () => {
return {
prop: 'name',
label: 'nickname',
}
},
},
})
</script>
// component-render.vue文件
<template>
<render />
</template>
<script setup lang="ts" name="ComponentRender">
const props = defineProps(['opt', 'data'])
const render = () => {
let renderH = props.opt.renderH
if (typeof renderH === 'function') {
return renderH(props.data, props.opt)
}
}
</script>
// mixin.ts文件
// 字段
export interface IField {
name?: string //名称
nickname?: string //中文label
prop?: string //名称
label?: string //中文label
htmlType?: string
minWidth?: number //该列的宽度
options?: any //该列的字典类型或可选值
optionKey?: string // 字典对应的键值
children?: IField[]
renderH?: (row: any, index: any) => globalThis.VNode<RendererNode, RendererElement, { [key: string]: any }>[] //渲染函数
}
// 字段使用的key值
export interface IFieldProp {
prop: string // 用什么值
label: string // 值的名称
}
//fields传入示例
fields.value = [
{
name: '',
nickname: '操作',
renderH: (row) => {
return [
h(
ElButton,
{ type: 'primary', link: true, onClick: () => handleEdit(row), icon: 'Edit' },
{ default: () => '修改' },
),
h(
ElButton,
{ type: 'danger', link: true, onClick: () => handleDelete(row), icon: 'Delete' },
{ default: () => '删除' },
),
]
},
},
]