element-ui的树形数据与懒加载这个似乎没办法级联选中,本来打算给rp一下的,但element的项目我实在是运行不起来,再者就算rp了,作者大概率也不会采纳。我就在业务模块中修改了一下.
级联勾选中,indeterminate(不确定状态)没有实现,也就是若所有的子节点被选中了,那么父节点会被勾选,若是有任意子节点未被选中,那么父节点不会被勾选,不会出现不确定状态
实现主要是通过el-table上面的两个事件select和select-all来实现的,select-all是表格全选的事件,我发现全选的时候,除了一级的节点外,二三级节点都不会被选中,所以也实现了一下
我发现还有一种需求,是只要有任意一个子节点被选中,那么父节点就也被选中,所有的子节点都被取消选中,那么父节点也要取消选中,代码我也写到后面去了
这些操作完毕以后,要获取所有被选中的数据,这里数据可能需要被处理一下,因为对于每个选中数据,可能拥有children属性,而children属性下面的子数据可能并非是我们选中的数据,这些数据处理我也实现了,但上面两种情况的数据处理方式不太相同,若是真的有人需要的话可以跟我交流哈
示例地址 github
<template>
<div id="app">
<el-table
ref="multipleTable"
:data="tableData"
style="width: 100%;margin-bottom: 20px;"
row-key="id"
border
default-expand-all
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
@select="handleSelect"
@select-all="handleSelectAll"
@selection-change="debounceHandleSelectionChange"
>
<el-table-column
type="selection"
width="55"
/>
<el-table-column
prop="date"
label="日期"
sortable
width="180"
/>
<el-table-column
prop="name"
label="姓名"
sortable
width="180"
/>
<el-table-column
prop="address"
label="地址"
/>
</el-table>
</div>
</template>
<script>
import { debounce } from 'lodash'
export default {
data() {
return {
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 弄',
children: [{
id: 311,
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
id: 312,
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
id: 313,
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 弄'
}],
multipleSelection: []
}
},
created() {
this.debounceHandleSelectionChange = debounce(this.handleSelectionChange)
},
methods: {
handleSelectionChange(val) {
console.log(val)
this.multipleSelection = val
},
handleSelectAll() {
const isAllSelected = this.$refs.multipleTable.store.states.isAllSelected
var _handleSelectAll = (data) => {
data.forEach(item => {
this.$refs.multipleTable.toggleRowSelection(item, isAllSelected)
_handleSelectAll(item.children || [])
})
}
_handleSelectAll(this.tableData)
},
handleSelect(selection, current) {
// 判断selection中是否存在current,若是存在那么就代表是被勾选上了,若是不存在代表是取消勾选了
const isChecked = !!selection.find(item => item.id === current.id)
// 如果当前项被取消勾选
if (!isChecked) {
// 那么其所有的祖先也应该被取消勾选
this.uncheckedParents(selection, current)
// 那么其所有的后代也应该被取消勾选
this.toggleCheckedChildrens(selection, current, false)
} else { // 如果当前项被勾选
// 那么若同一组的元素都被勾选了,那么父元素将也被勾选,依次往上类推
this.checkedParents(selection)
// 那么其所有的后代都要被勾选
this.toggleCheckedChildrens(selection, current, true)
}
},
toggleCheckedChildrens(selection, item, isChecked) {
var _toggleCheckedChildrens = (data) => {
data.find(element => {
this.$refs.multipleTable.toggleRowSelection(element, isChecked)
if (isChecked && !selection.find(item => item.id === element.id)) {
selection.push(element)
} else if (!isChecked && selection.find(item => item.id === element.id)) {
for (let i = selection.length - 1; i >= 0; i--) {
if (selection[i].id === element.id) {
selection.splice(i, 1)
break
}
}
}
_toggleCheckedChildrens(element.children || [])
})
}
_toggleCheckedChildrens(item.children || [])
},
checkedParents(selection) {
var _checkedParents = (element) => {
const children = element.children
if (children && children.length) {
const allChildrenChecked = children.every(child => {
return _checkedParents(child)
})
if (allChildrenChecked) {
this.$refs.multipleTable.toggleRowSelection(element, true)
if (!selection.find(item => item.id === element.id)) {
selection.push(element)
}
}
}
return selection.find(item => item.id === element.id)
}
this.tableData.forEach(element => {
_checkedParents(element)
})
},
uncheckedParents(selection, item) {
var _uncheckedParents = (data) => {
return data.find(element => {
if (element.id === item.id) {
return true
} else if (_uncheckedParents(element.children || [])) {
this.$refs.multipleTable.toggleRowSelection(element, false)
for (let i = selection.length - 1; i >= 0; i--) {
if (selection[i].id === element.id) {
selection.splice(i, 1)
break
}
}
return true
} else {
return false
}
})
}
_uncheckedParents(this.tableData)
}
}
}
</script>
只要有任意一个子节点被选中,那么父节点就也被选中的代码示例
<template>
<div id="app">
<el-table
ref="multipleTable"
:data="tableData"
style="width: 100%;margin-bottom: 20px;"
row-key="id"
border
default-expand-all
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
@select="handleSelect"
@select-all="handleSelectAll"
@selection-change="debounceHandleSelectionChange"
>
<el-table-column
type="selection"
width="55"
/>
<el-table-column
prop="date"
label="日期"
sortable
width="180"
/>
<el-table-column
prop="name"
label="姓名"
sortable
width="180"
/>
<el-table-column
prop="address"
label="地址"
/>
</el-table>
</div>
</template>
<script>
import { debounce } from 'lodash'
export default {
data() {
return {
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 弄',
children: [{
id: 311,
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
id: 312,
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
id: 313,
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 弄'
}],
multipleSelection: []
}
},
created() {
this.debounceHandleSelectionChange = debounce(this.handleSelectionChange)
},
methods: {
handleSelectionChange(val) {
console.log(val)
this.multipleSelection = val
},
handleSelectAll(selection) {
const isAllSelected = this.$refs.multipleTable.store.states.isAllSelected
var _handleSelectAll = (data) => {
data.forEach(item => {
this.$refs.multipleTable.toggleRowSelection(item, isAllSelected)
_handleSelectAll(item.children || [])
})
}
_handleSelectAll(this.tableData)
},
handleSelect(selection, current) {
// 判断selection中是否存在current,若是存在那么就代表是被勾选上了,若是不存在代表是取消勾选了
const isChecked = !!selection.find(item => item.id === current.id)
// 如果当前项被取消勾选
if (!isChecked) {
// 那么其所有的后代也应该被取消勾选
this.toggleCheckedChildrens(selection, current, false)
// 那么若是所有的兄弟都被取消勾选的话,其祖先也应该被取消勾选
this.uncheckedParents(selection, current)
} else { // 如果当前项被勾选
// 那么若同一组的元素都被勾选了,那么父元素将也被勾选,依次往上类推
this.checkedParents(selection)
// 那么其所有的后代都要被勾选
this.toggleCheckedChildrens(selection, current, true)
}
},
toggleCheckedChildrens(selection, item, isChecked) {
var _toggleCheckedChildrens = (data) => {
data.find(element => {
this.$refs.multipleTable.toggleRowSelection(element, isChecked)
if (isChecked && !selection.find(item => item.id === element.id)) {
selection.push(element)
} else if (!isChecked && selection.find(item => item.id === element.id)) {
for (let i = selection.length - 1; i >= 0; i--) {
if (selection[i].id === element.id) {
selection.splice(i, 1)
break
}
}
}
_toggleCheckedChildrens(element.children || [])
})
}
_toggleCheckedChildrens(item.children || [])
},
checkedParents(selection) {
var _checkedParents = (element) => {
const children = element.children
if (children && children.length) {
const anyChildrenChecked = children.some(child => {
return _checkedParents(child)
})
if (anyChildrenChecked) {
this.$refs.multipleTable.toggleRowSelection(element, true)
if (!selection.find(item => item.id === element.id)) {
selection.push(element)
}
}
}
return selection.find(item => item.id === element.id)
}
this.tableData.forEach(element => {
_checkedParents(element)
})
},
uncheckedParents(selection, item) {
var _uncheckedParents = (element) => {
const children = element.children
if (children && children.length) {
const allChildrenUnChecked = children.every(child => {
return _uncheckedParents(child)
})
if (allChildrenUnChecked) {
this.$refs.multipleTable.toggleRowSelection(element, false)
for (let i = selection.length - 1; i >= 0; i--) {
if (selection[i].id === element.id) {
selection.splice(i, 1)
break
}
}
return true
} else {
return false
}
}
return selection.every(item => item.id !== element.id)
}
this.tableData.forEach(element => {
_uncheckedParents(element)
})
}
}
}
</script>