前言:
对element的列表二次进行封装,让他能支持树形数据中添加复选框,并支持render与slot的使用。
实现效果:
实现步骤:
1、引入封装代码 checkTable
import checkTable from '@/views/pages/system/user/checkTable'
components:{
checkTable
},
2、页面调用,使用插槽,最大的还原element的写法
template内部:
<checkTable :tableData="tableData" :columns="columns">
<el-table-column
slot="date"
label="日期"
width="180">
<template slot-scope="scope">
<span>{
{ scope.row.date }}</span>
</template>
</el-table-column>
<el-table-column
slot="name"
label="姓名"
width="180">
<template slot-scope="scope">
<span>{
{ scope.row.name }}</span>
</template>
</el-table-column>
<el-table-column
slot="address"
label="地址"
width="180">
<template slot-scope="scope">
<span>{
{ scope.row.address }}</span>
</template>
</el-table-column>
</checkTable>
data:
data(){
return{
//列表数据,带children的是有子级的
tableData:[
{
id: 1,
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
id: 2,
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
id: 3,
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄',
children: [{
id: 31,
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
id: 32,
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}]
}, {
id: 4,
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}
],
//表头
columns:[
{slot:'date'},
{slot:'name'},
{slot:'address'},
]
3、页面调用-js中定义
<checkTable :tableData="tableData" :columns="columns"></checkTable>
data:
data(){
return{
//列表数据,带children的是有子级的
tableData:[
{
id: 1,
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
id: 2,
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
id: 3,
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄',
children: [{
id: 31,
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
id: 32,
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}]
}, {
id: 4,
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}
],
//表头
columns:[
{
prop:'name',
title:'姓名',
align:'center',
width:150,
},
...
]
封装源码:checkTable.vue
<template>
<el-table
ref="multipleTable"
border
:data="tableData"
row-key="id"
:default-expand-all="true"
:tree-props="{hasChildren: 'hasChildren',children: 'children'}"
>
<el-table-column width="80">
<template slot="header" slot-scope="scope">
<el-checkbox
v-model="allCheckout"
style="padding-left: 10px"
@change="checkAllFun()"
/>
</template>
<template slot-scope="scope">
<el-checkbox
v-model="scope.row.checks"
style="padding-left: 10px"
@change="checkChange(scope.row)"
/>
</template>
</el-table-column>
<template v-for="(column, index) in columns">
<!-- slot 添加自定义配置项 -->
<slot v-if="column.slot" :name="column.slot" :tit='index'></slot>
<!-- 默认渲染列-渲染每一列的汉字 -->
<el-table-column
v-else
:prop="column.prop"
:label="column.title"
:align="column.align"
:width="column.width"
:show-overflow-tooltip="true">
<template slot-scope="scope">
<!--正常渲染-->
<template v-if="!column.render">
<template v-if="column.formatter">
<span v-html="column.formatter(scope.row, column)"></span>
</template>
<template v-else>
<span>{
{scope.row[column.prop]}}</span>
</template>
</template>
<!--render函数-->
<template v-else>
<expandDom :column="column" :row="scope.row" :render="column.render" :index="index"></expandDom>
</template>
</template>
</el-table-column>
</template>
</el-table>
</template>
<script>
/**
* @封装的复选框加列表expend展开功能列表
* @createTime 2023.6
* @auth ry
* */
export default {
name: "checkTable.vue",
props:{
// 表格数据
tableData:{
type: Array,
deep:true,
immediate:true,
default:()=>[]
},
//表头
columns: {
type:Array,
default:()=>[]
},
tableClass: {
type: String,
default: 'checkTable'
},
},
components: {
/**
* render函数渲染组件
* */
expandDom: {
functional: true,
props: {
row: Object,
render: Function,
index: Number,
column: {
type: Object,
default: null
}
},
render: (h, ctx) => {
const params = {
row: ctx.props.row,
index: ctx.props.index
}
if (ctx.props.column) params.column = ctx.props.column
return ctx.props.render(h, params)
}
}
},
data(){
return{
// tableData: [],
mapData: [],
allCheckout: false, //全选
}
},
methods:{
// 获取当前选中的数据
getNowSelData(){
let selData = []
this.tableData.forEach(item=>{
// 一级无子级
if(item.checks && !item.children){
selData.push(item)
}
// 一级有子级
if(item.checks && item.children && item.children.length){
selData.push(item)
selData = selData.concat(item.children)
}
// 二级无子级
if(!item.checks && item.children && item.children.length){
item.children.forEach(two=>{
if(two.checks){
selData.push(two)
}
})
}
})
return selData
},
// 获取当前选中的数据-只有一级数据
getNowSelDataOneType(){
let selData = []
this.tableData.forEach(item=> {
// 一级无子级
if (item.checks) {
selData.push(item)
}
})
return selData
},
// 总全选点击事件
checkAllFun() {
this.$refs.multipleTable.data.forEach(items => {
this.$set(items, "checks", this.allCheckout);
if (items.children) {
items.children.forEach((item) => {
this.$set(item, "checks", this.allCheckout);
});
}
});
},
//插槽复选框逻辑
checkChange(row) {
// expend 父级复选框
if (row.children) {
if (row.checks) {
row.children.map((item) => {
this.$set(item, "checks", true);
});
this.$set(row, "checks", true);
// this.mag = true;
} else {
row.children.map((item) => {
this.$set(item, "checks", false);
});
this.$set(row, "checks", false);
}
return
}
// 子带父
this.mapData = []
// 一级无子级的,或者二级无子级的
this.$set(row, "checks", row.checks)
const findTypeArr = this.tableData.filter(v=>v.id == row.id)
let jb_type = ''
if(findTypeArr.length>0){
jb_type = '1'
}else{
jb_type = '2'
}
// 一级的操作
if(jb_type == '1' && !row.checks){
this.allCheckout = false
}
if(jb_type == '1' && row.checks){
this.allCheckSetFun()
}
// 二级操作
if(jb_type == '2' && !row.checks){
this.allCheckout = false
this.tableData.forEach(one => {
if (one.children && one.children.length > 0) {
one.children.forEach(two => {
if (two.id == row.id) {
this.$set(one, "checks", false)
}
})
}
})
}
if(jb_type == '2' && row.checks){
this.tableData.forEach(one => {
if (one.children && one.children.length > 0) {
one.children.forEach(two => {
if (two.id == row.id) {
let twoSelArr = one.children.filter(v=>v.checks)
if(twoSelArr.length == one.children.length){
this.$set(one, "checks", true)
}else{
this.$set(one, "checks", false)
}
}
})
}
})
this.allCheckSetFun()
}
},
// 修改外部总勾选
allCheckSetFun(){
let oneSelArr = this.tableData.filter(v=>v.checks)
if(oneSelArr.length == this.tableData.length){
this.allCheckout = true
}else{
this.allCheckout = false
}
},
}
}
</script>
<style type="scss" scoped>
</style>