使用方法(将这个注册为组件再使用) 根据element 的 el-table 组件再次封装
<TableTrees ref="tabTree" :check-list="tableList" :tree-data="treeData" :parent-key="'parentId'" :tree-props="treeProps" :data-column="dataColumn" :row-key="'targetId'" @tabSelectChange="tabSelectChange" />
参数说明 :
:tree-data = treeData 展示的树参数 (树形)(必传)
:check-list = tableList 默认勾选参数
:parent-key = parentId 父id的名称(key)(必传)
:tree-props = treeProps 树形参数的对象(必传)
:row-key = targetId 根据什么参数判断是否是树(element表格组件自带的)
:data-column = dataColumn 表格字段(必传)
@tabSelectChange 复选框勾选事件 (返回勾选参数的数组)
dataColumn = [
{ prop: 'code', label: '指标编码' },
{ prop: 'name', label: '指标名称', align: 'center' },
{ prop: 'scoreMode', label: '评分方式', align: 'center' }
]
表格树组件代表
<template>
<el-table
ref="tabled"
class="sel-table"
:expand-row-keys="defaultExpandAll"
:data="dataTree"
:tree-props="treeProps"
:row-key="rowKey"
border
>
<el-table-column label="#" width="80" :render-header="renderHeader">
<template slot-scope="scope">
<el-checkbox :key="checkboxDatas.length" v-model="scope.row.checked" @change="tabSelectChange(scope.row)" />
</template>
</el-table-column>
<template v-for="(item,index) in dataColumn">
<el-table-column
:key="index"
:label="item.label"
:prop="item.prop"
:fixed="item.fixed"
:type="item.type"
:width="item.width"
:class-name="item.class"
:min-width="item.minWidth"
:align="item.align"
:show-overflow-tooltip="item.showTooltip"
/>
</template>
<!-- <el-table-column prop="code" label="指标编码" />-->
<!-- <el-table-column prop="name" label="指标名称" align="center" />-->
<!-- <el-table-column prop="scoreMode" label="评分方式" align="center" />-->
</el-table>
</template>
<script>
export default {
name: 'Index',
props: {
treeData: {
type: Array,
default: () => []
},
treeProps: {
type: Object,
default: () => {}
},
// 更具什么key判断参数是否存在
rowKey: {
type: String,
default: ''
},
dataColumn: {
type: Array,
default: () => []
},
parentKey: {
type: String,
default: ''
},
checkList: {
type: Array,
default: () => []
}
},
data() {
return {
checkboxDatas: [],
defaultExpandAll: []
}
},
computed: {
dataTree() {
let tmp
if (!Array.isArray(this.treeData)) {
tmp = [this.treeData]
} else {
tmp = this.treeData
}
return tmp
}
},
/* created() {
if (this.dataTree.length > 0) {
this.dataTree.forEach(x => {
this.recursiveCheck(x, false)
})
}
},*/
mounted() {
this.$nextTick(() => {
var that = this
// 初始化 checked为false
that.dataTree.forEach(x => {
that.recursiveCheck(x, false)
})
// 拿到默认勾选的参数
if (that.checkList != undefined) {
that.dataTree.forEach(x => {
that.checkList.forEach(j => {
if (x[that.rowKey] == j[that.rowKey]) { // 循环判断,如果相等就调用勾选方法勾选
x.checked = true
that.tabSelectChange(x)
}
})
})
}
// 最顶上的复选框chanage事件
const all = document.getElementById('chooseall')
all.onchange = function(e) {
if (that.dataTree.length > 0) {
that.dataTree.forEach(x => {
x.checked = all.checked
that.tabSelectChange(x)
// that.recursiveCheck(x, all.checked)
})
// document.getElementById('spand').className += ' el-checkbox__input is-checked' // 设置全选框全选
}
/* if (all.checked === true) {
document.getElementById('spand').className += ' el-checkbox__input is-checked' // 设置全选框全选
} else {
document.getElementById('spand').className = 'el-checkbox__input' // 设置全选框的状态
}*/
}
})
},
methods: {
tabSelectChange(row) {
this.recursiveCheck(row, row.checked)
var arrListTree = this.treeToList(this.checkboxDatas)
var jsonTab1 = JSON.parse(JSON.stringify(this.checkboxDatas))
if (row.checked === true) { // 添加
if (this.checkboxDatas.length <= 0) {
this.checkboxDatas.push(row)
} else {
var bool = true
// 如果父id不存在,那么就是顶级,直添加
if (row[this.parentKey] == undefined) {
// 循环判断当前表格内的参数是否存在是当前父级的子集 如果存在则调用递归删除后在添加,否则直接添加
var i = 0
while (i < jsonTab1.length) {
if (jsonTab1[i][this.parentKey] == row[this.rowKey] || jsonTab1[i][this.rowKey] == row[this.rowKey]) {
jsonTab1.splice(i, 1)
} else {
i++
}
}
jsonTab1.push(row)
} else {
for (let i = 0; i < arrListTree.length; i++) {
// 如果当前表格内存在父级参数,则递归添加
if (arrListTree[i][this.rowKey] == row[this.parentKey]) {
jsonTab1.forEach(x => {
if (x[this.rowKey] == row[this.parentKey]) { // 判断是否是当前想的子集 如果是子集 这直接添加
x.children.push(row)
bool = false
} else { // 否则递归添加
this.addTree(x, row[this.parentKey], row, bool)
}
})
} else {
// 判断选择参数的子是否存在表格内 存在则删除
if (arrListTree[i][this.parentKey] == row[this.rowKey]) {
for (let j = 0; j < jsonTab1.length; j++) {
if (jsonTab1[j][this.parentKey] == row[this.rowKey]) {
jsonTab1.splice(j, 1)
}
}
}
}
}
if (bool === true) {
jsonTab1.push(row)
}
}
this.checkboxDatas = jsonTab1
}
} else { // 删除
for (let i = 0; i < jsonTab1.length; i++) {
if (jsonTab1[i][this.rowKey] == row[this.rowKey]) {
jsonTab1.splice(i, 1)
} else {
this.removerTree(jsonTab1[i], row[this.rowKey])
}
}
// this.recursiveCheck(row, row.checked)
this.checkboxDatas = jsonTab1
}
this.$nextTick(() => {
arrListTree.forEach(x => {
this.defaultExpandAll.push(x[this.rowKey])
})
})
this.selectClick()
},
selectClick() {
this.$nextTick(() => {
if (this.checkboxDatas.length == this.dataTree.length) {
document.getElementById('spand').className = 'el-checkbox__input is-checked' // 设置全选框全选
document.getElementById('spand').checked = true // 设置全选框全选
} else if (this.checkboxDatas.length != 0) {
document.getElementById('spand').className += ' is-indeterminate' // 设置全选框的半选
} else {
document.getElementById('spand').className = 'el-checkbox__input' // 设置全选框未选中状态
}
})
this.$emit('tabSelectChange', this.checkboxDatas)
},
// 递归遍历勾选的
recursiveCheck(row, checked) {
row.checked = checked
if (row.children != undefined) {
row.children.forEach(x => {
x.checked = checked
if (x.children != undefined) {
this.recursiveCheck(x, checked)
}
})
}
},
// 动态添加
addTree(data, id, row, bool) {
if (data.children != undefined) {
for (let i = 0; i < data.children.length; i++) {
if (data.children[i][this.rowKey] == id) {
data.children.push(row)
bool = false
break
} else {
this.addTree(data.children[i], id, row, bool)
}
}
}
},
// 删除选择的元素
removerTree(data, id) {
if (data.children != undefined) {
for (let i = 0; i < data.children.length; i++) {
if (data.children[i][this.rowKey] == id) { // 递归到选中的id和表格内子集的id相同 就删除
data.children.splice(i, 1)
break
} else {
this.removerTree(data.children[i], id)
}
}
}
},
// 扁平结构 用于判断
treeToList(tree) {
var queen = []
var out = []
queen = queen.concat(tree)
while (queen.length) {
var first = queen.shift()
if (first.children != undefined && first.children) {
queen = queen.concat(first.children)
}
out.push(first)
}
return out
},
// 头部的单选框
renderHeader(h, data) {
return h(
'label',
{
attrs: {
id: 'labels',
role: 'checkbox',
class: 'el-checkbox el-text'
}
},
[
h(
'span',
{
attrs: {
id: 'spand',
'aria-checked': 'mixed',
class: 'el-checkbox__input'
}
},
[
h('span', {
attrs: {
class: 'el-checkbox__inner'
}
}),
h('input', {
attrs: {
id: 'chooseall',
'aria-hidden': 'true',
type: 'checkbox',
style: 'display: none'
/* style:
'border: 1px solid #dcdfe6;border-radius: 2px;box-sizing: border-box;width: 14px;height: 14px;background-color: #fff;'*/
}
})
]
)
]
)
}
}
}
</script>
<style lang="scss" scoped>
/deep/.el-text{
margin-left: 35%;
}
/deep/.el-table__indent{
padding-left: 10px !important;
}
</style>
效果图