封装的el-table公共组件table.vue
注意深拷贝用的lodash方法,以及使用了jsx渲染列的标签和事件
<template>
<div class="page-view flex-center">
<el-table v-loading="tableData.tableLoading" ref="multipleTableRef" class="jg-table" :data="tableData.data"
style="width: 100%;" @selection-change="handleSelectionChange" @row-click="rowClick" @sort-change="sortChange">
<template v-for="(item, index) in tableData.columnsData " :key="index">
<!-- 多选 -->
<el-table-column v-if="item.type === 'selection'" :type="item.type" :width="item.width" />
<!-- 单选 -->
<el-table-column v-else-if="item.type === 'radio'" :width="item.width" class-name="no-radio-label">
<template #default="{ row, $index }">
<el-radio @change="changeRadio" v-model="radioIndex" :label="row"></el-radio>
</template>
</el-table-column>
<!-- 渲染formatter -->
<el-table-column v-else :property="item.field" :label="item.title" :width="item.width" :min-width="item.minWidth"
:max-idth="item.maxWidth" :showOverflowTooltip="item.showOverflowTooltip" :sortable="item.sortable"
:formatter="item.formatter" />
</template>
</el-table>
</div>
</template>
<script lang="jsx">
import { ref, defineComponent, getCurrentInstance, h } from 'vue' // 按需引入ref函数
import { Delete, Edit, Download, QuestionFilled, EditPen, Tickets } from '@element-plus/icons-vue'
export default defineComponent({
name: 'JgTable',
props: {
tableDataObj: { // 父组件传递的表格数据
type: Object,
default: () => {
return {}
}
},
},
emits: ['update:editItem'],
setup(props, { emit }) {
const { proxy } = getCurrentInstance()
let tableData = ref({})
let radioIndex = ref(null)
watch([() => props.tableDataObj, () => props.rulesData], ([tableDataObj, rulesData]) => {
console.log('监听');
tableData.value = proxy.$_.cloneDeep(tableDataObj) // 注意深拷贝的方法 我用的lodash的
// rules.value = proxy.$_.cloneDeep(rulesData)
}, { deep: true, immediate: true })
// 编辑操作
function editItem(row, type) {
console.log(row, type,);
// 子传父
emit('update:editItem', { row: row, type: type });
}
const myDiv = () => h('div', null, 'Hello, 1')
// 多选
const handleSelectionChange = (val) => {
console.log(val);
// 子传父
emit('update:handleSelectionChange', val);
}
// 单选
const changeRadio = (val) => {
// console.log('单选', val, radioIndex.value.aa);
emit('update:changeRadio', val);
}
// 表格点击事件
const rowClick = (val) => {
// console.log(val);
}
// 排序
const sortChange = (val) => {
// console.log(val);
emit('update:sortChange', val);
}
// 将变量和函数返回,以便在模版中使用
return {
myDiv,
radioIndex,
tableData,
editItem,
handleSelectionChange,
changeRadio,
rowClick,
sortChange,
EditPen,
Tickets,
}
}
})
</script>
<style lang="scss" scoped>
// 去除单选框的内容
:deep(.no-radio-label) {
.el-radio__label {
display: none;
}
}
</style>
父组件far.vue使用封装的表格
<template>
<JgTable :tableDataObj="tableData" @update:editItem="updateEditItem" @update:handleSelectionChange="updateHandleSelectionChange" @update:changeRadio="updateChangeRadio" @update:sortChange="updateSortChange"></JgTable>
</template>
对应表格数据
let tableData = ref({
tableLoading: false,
// title:名称 field:key type:单选复选框 width minWidth maxWidth showOverflowTooltip formatter:格式化内容
columnsData: [
{ title: '多选', type: 'selection', width: 55 },
// { title: '单选', type: 'radio', width: 55 },
{ title: '缺陷名称', field: 'aa', formType: 'input', width: 120 },
{ title: '缺陷描述', field: 'bb', formType: 'input', showOverflowTooltip: true },
{ title: '缺陷发布时间', field: 'cc', formType: 'date', dateType: 'YYYY-MM-DD', width: 140 },
// { title: '缺陷发布时间', field: 'cc', formType: 'datetime', dateType: 'YYYY-MM-DD HH:mm:ss' },
{
title: '设备类型', field: 'dd', formType: 'select', width: 120, selectList: [
{ name: '横向隔离', value: 0 },
{ name: '纵向加密', value: 1 },
{ name: '防火墙', value: 2 },
{ name: '监测装置', value: 3 },
{ name: '运维网关', value: 4 },
{ name: '其他', value: 5 },
],
formatter: (row) => {
const val = [
{ name: '横向隔离', value: 0 },
{ name: '纵向加密', value: 1 },
{ name: '防火墙', value: 2 },
{ name: '监测装置', value: 3 },
{ name: '运维网关', value: 4 },
{ name: '其他', value: 5 },
].find(item => item.value === row.dd)?.name || ''
return <span>{val}</span>
}
},
{ title: '设备厂家', field: 'ee', formType: 'input' },
{ title: '设备版本', field: 'ff', formType: 'input', width: 160, showOverflowTooltip: true },
{ title: '缺陷设备数量', field: 'gg', formType: 'input', sortable: 'custom' },
{
title: '缺陷反馈状态', field: 'hh', formType: 'radio', minWidth: 100, selectList: [
{ name: '已反馈', value: 1 },
{ name: '未反馈', value: 0 },
],
formatter: (row) => (
row ? <el-tag style="border: none;" class="cursor" type={row.hh === 1 ? 'green' : 'warning'}>{row.hh === 1 ? '已反馈' : row.hh === 0 ? '未反馈' : ''}</el-tag> : ''
)
},
{
title: '缺陷处置进度', field: 'ii', formType: 'progress',
formatter: (row) => (
<el-progress class="table_progress" width="13" stroke-width="2" type="circle" percentage={row.ii} />
)
},
// {
// title: '测试', field: 'ceshi',width: 200,
// formatter: (row, column) => {
// // console.log(112,row, column); // 直接{row}或{column} 不会显示内容
// return [<el-tag type={row.ceshi == "可发放" ? "success" : "danger"} onClick={() => editItem(row, 'view')}> {row.ceshi} </el-tag>, <span>{column.label}</span>]
// }
// },
{
title: '操作', field: 'caozuo', width: 140,
formatter: (row) => (
[
<el-button link type="primary" size="small" icon={Tickets} onClick={() => editItem(row, 'view')} > 查看</el-button >,
<el-button link type="primary" size="small" icon={EditPen} onClick={() => editItem(row, 'edit')} > 编辑</el-button >
]
)
},
],
data: Array.from({ length: 7 }).map((ele, index) => {
return {
aa: '客户端不适配',
bb: '客户端无法适配凝思 4.2.40',
cc: '2023-7-20',
dd: proxy.$_.random(0, 3),
ee: '帕拉迪',
ff: 'PLD Sys 61012100',
gg: proxy.$_.random(0, 20),
hh: proxy.$_.random(0, 1),
ii: proxy.$_.random(0, 100),
ceshi: 123,
}
})
})
对应方法
// 子组件调用父组件的测试事件
const updateEditItem =(data)=>{
console.log('子组件调用父组件的测试事件',data);
editItem(data.row,data.type)
}
const updateHandleSelectionChange =(data)=>{
if (data.length > 0) {
feedbackFlag.value = false
} else {
feedbackFlag.value = true
}
}
const updateChangeRadio =(data)=>{
console.log(data);
if (data) {
feedbackFlag.value = false
} else {
feedbackFlag.value = true
}
}
const updateSortChange =(data)=>{
console.log(data);
}