示例页面地址
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Element-UI 树表格级联选择</title>
<link rel="stylesheet" href="https://unpkg.com/element-ui@2.15.9/lib/theme-chalk/index.css">
</head>
<body>
<div id="app">
<el-table border ref="multipleTable"
:data="list" tooltip-effect="dark" style="width: 100%"
@selection-change="handleSelectionChange"
row-key="id" default-expand-all
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
@select="handleSelect"
@select-all="handleSelectAll">
<el-table-column align="center" type="selection" width="55"></el-table-column>
<el-table-column label="日期" width="160">
<template slot-scope="scope">{{ scope.row.date }}</template>
</el-table-column>
<el-table-column prop="name" label="姓名" width="120">
</el-table-column>
<el-table-column prop="address" label="地址" show-overflow-tooltip>
</el-table-column>
</el-table>
</div>
<script src="https://unpkg.com/vue@2"></script>
<script src="https://unpkg.com/element-ui"></script>
<script>
Vue.use(ELEMENT)
function treeToList(list, children, out = []) {
list.forEach(item => {
out.push(item);
if (item[children]?.length) {
treeToList(item[children], children, out)
}
})
return out;
}
new Vue({
el: '#app',
data() {
return {
list: [],
multipleSelection: [],
// 配置
setting:{
childrenKey:'children',
idKey:'id',
pidKey:'pid',
listPropName:'list',
tableRef:'multipleTable'
}
}
},
computed: {
allRows() {
return treeToList(this[this.setting.listPropName],this.setting.childrenKey)
},
},
mounted(){
queryData().then(list=>this.list = list);
},
methods: {
/**选中状态改变 */
handleSelectionChange(val) {
this.multipleSelection = val;
},
/**单行选中 */
handleSelect(selection, row) {
let checked = selection.includes(row);
if (checked) {
this.selectedParents(selection,row);
this.toggleRowSelections(row.children, true)
} else {
this.unSelectedParents(row)
this.toggleRowSelections(row.children, false)
}
},
/**检查并选中父级节点 */
selectedParents(selection,row) {
let parent = this.getParentRow(row)
if (!parent) { return }
// 所有有兄弟节点均已被选中
if (!parent.children.find(item => !selection.includes(item))) {
// 选中当前节点
this.toggleRowSelection(parent, true)
// 并继续向上检索
this.selectedParents(selection,parent);
}
},
/**行取消选中后 */
unSelectedParents(row) {
let parent = this.getParentRow(row);
while (parent) {
this.toggleRowSelection(parent, false)
parent = this.getParentRow(parent);
}
},
getParentRow(row) {
return this.allRows.find(item => item.id === row.pid)
},
/** 设置树形列表选中状态 */
toggleRowSelections(list, checked) {
list?.forEach(item => {
this.toggleRowSelection(item, checked)
if (item[this.setting.childrenKey]?.length) {
this.toggleRowSelections(item[this.setting.childrenKey], checked);
}
})
},
toggleRowSelection(row, checked) {
this.$refs[this.setting.tableRef].toggleRowSelection(row, checked)
},
/**全选 */
handleSelectAll(selection) {
let noroots = this.allRows.length - this.list.length;
let selnoroots = selection.filter(item => item[this.setting.pidKey] !== 0).length;
let selroots = selection.filter(item => item[this.setting.pidKey] === 0).length;
if ((selroots === 0)) {
if (noroots === selnoroots) {
this.toggleRowSelections(this.list, false);
return;
}
}
this.toggleRowSelections(this.list, true);
},
}
})
function queryData() {
return Promise.resolve([
{
id: 1, pid: 0, date: "2016-05-02", name: "wangxiaohu",
children: [
{ id: 11, pid: 1, date: "2016-05-04", name: "wangxiaohu" },
{ id: 12, pid: 1, date: "2016-05-04", name: "wangxiaohu" },
{ id: 13, pid: 1, date: "2016-05-04", name: "wangxiaohu" },
]
},
{ id: 2, pid: 0, date: "2016-05-04", name: "wangxiaohu" },
{ id: 3, pid: 0, date: "2016-05-04", name: "wangxiaohu" },
{ id: 4, pid: 0, date: "2016-05-04", name: "wangxiaohu" },
{ id: 5, pid: 0, date: "2016-05-04", name: "wangxiaohu" },
])
}
</script>
</body>
</html>