hrm
parent
bd50c3fc95
commit
0580b9876e
|
|
@ -0,0 +1,126 @@
|
|||
明白你的实际需求是这样的:
|
||||
|
||||
✅ 你有多个类似的表单表格页面
|
||||
结构类似,都是用 <el-table> + <el-table-column> 组成。
|
||||
|
||||
不想复制粘贴逻辑去控制字段显示与否。
|
||||
|
||||
✅ 每个账号登录后,后端会返回字段权限控制数组
|
||||
例如:
|
||||
|
||||
json
|
||||
复制
|
||||
编辑
|
||||
["customerName", "companyAccount", "companyAddress"]
|
||||
你希望根据这个字段列表来自动控制每一列是否显示,不再手动加 v-if="showField('xxx')"。
|
||||
|
||||
✅ 目标:让字段显示/隐藏逻辑封装好,不影响页面使用结构
|
||||
你想要的最终效果是:
|
||||
|
||||
vue
|
||||
复制
|
||||
编辑
|
||||
<!-- 外部写法保持不变,只改 el-table 为 FormTable -->
|
||||
<FormTable :data="formData" :visible-fields="visibleFields">
|
||||
<el-table-column label="序号" type="index" width="100" />
|
||||
|
||||
<el-table-column label="单位名称" prop="customerName">
|
||||
<!-- 表单结构 -->
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="开户账号" prop="companyAccount">
|
||||
<!-- 表单结构 -->
|
||||
</el-table-column>
|
||||
</FormTable>
|
||||
✅ 解决方案:封装 FormTable,自动隐藏字段(通过 prop 字段)
|
||||
我们只需要在封装组件中 拦截 slot 中的 el-table-column,判断其 prop 是否在权限字段中,不在就不渲染。
|
||||
|
||||
✅ 封装组件 FormTable.vue
|
||||
vue
|
||||
复制
|
||||
编辑
|
||||
<template>
|
||||
<el-table :data="data" v-bind="$attrs" class="-mt-10px">
|
||||
<component
|
||||
v-for="(vnode, index) in filteredColumns"
|
||||
:is="vnode"
|
||||
:key="index"
|
||||
/>
|
||||
</el-table>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useSlots, computed } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
data: any[]
|
||||
visibleFields: string[] // 后端返回的字段权限列表
|
||||
}>()
|
||||
|
||||
const slots = useSlots()
|
||||
|
||||
// 处理 slots 中的 column,仅保留 prop 在 visibleFields 里的
|
||||
const filteredColumns = computed(() => {
|
||||
const defaultSlot = slots.default?.() || []
|
||||
|
||||
return defaultSlot.filter((vnode: any) => {
|
||||
// 保留不含 prop 的列(如序号/操作列)
|
||||
const prop = vnode.props?.prop
|
||||
if (!prop) return true
|
||||
return props.visibleFields.includes(prop)
|
||||
})
|
||||
})
|
||||
</script>
|
||||
✅ 父组件使用方式(完全一样,只加一个 visibleFields)
|
||||
vue
|
||||
复制
|
||||
编辑
|
||||
<FormTable :data="formData" :visible-fields="visibleFields">
|
||||
<el-table-column label="序号" type="index" width="100" />
|
||||
|
||||
<el-table-column label="单位名称" prop="customerName">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.customerName`" :rules="formRules.customerName">
|
||||
<el-input v-model="row.customerName" placeholder="请输入单位名称" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="开户账号" prop="companyAccount">
|
||||
<template #default="{ row, $index }">
|
||||
<el-form-item :prop="`${$index}.companyAccount`" :rules="formRules.companyAccount">
|
||||
<el-input v-model="row.companyAccount" placeholder="请输入开户账号" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 操作列不写 prop,自动保留 -->
|
||||
<el-table-column label="操作" fixed="right" width="60">
|
||||
<template #default="{ $index }">
|
||||
<el-button @click="handleDelete($index)" link>—</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</FormTable>
|
||||
✅ 后端返回字段控制
|
||||
你只需要从后端返回一个字段列表,比如:
|
||||
|
||||
ts
|
||||
复制
|
||||
编辑
|
||||
const visibleFields = ['customerName', 'companyAccount']
|
||||
然后传给 FormTable 即可:
|
||||
|
||||
vue
|
||||
复制
|
||||
编辑
|
||||
<FormTable :data="formData" :visible-fields="visibleFields">...</FormTable>
|
||||
✅ 总结优点
|
||||
✅ 只改 <el-table> 为 <FormTable>,其他逻辑不动。
|
||||
|
||||
✅ 无需手动每列写 v-if。
|
||||
|
||||
✅ 可根据后端返回字段权限自动显示/隐藏。
|
||||
|
||||
✅ 支持任意结构(form-item、插槽等)。
|
||||
|
||||
需要我帮你做完整的 .vue 文件模板或添加分页/loading 也可以继续说。
|
||||
Loading…
Reference in New Issue