1. Premise basis
- Master vue, element-UI related front-end knowledge, if you have not mastered the children’s shoes can first go to see my Vue family barrel: juejin.cn/post/684490… .
2. Service scenario description
- Suppose we now have a list of people who need to be assigned specific permissions to restrict who can do what:
3, code,
- Create authTree. vue page:
<template>
<div class="auth_tree">
<el-table
:data="listData"
border
style="width: 100%;">
<el-table-column label="ID" prop="id">
</el-table-column>
<el-table-column label="Name" prop="name">
</el-table-column>
<el-table-column label="Gender" prop="sex">
</el-table-column>
<el-table-column label="Permission Configuration">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="opetation(scope.row.auth)"> Configure </el-button> </template> </el-table-column> </el-table> <el-dialog :visible. Sync ="dialogVisible"
title="Configure Permissions"
center
width="600px"
@close="closeDialog">
<div class="dialog_main_content">
<el-tree
ref="tree"
:data="treeData"
:expand-on-click-node="false"
:show-checkbox="true"
node-key="id"
default-expand-all
@check="currentChecked"/>
</div>
<div class="dialog_footer">
<el-button @click="cancel"</el-button> <el-buttontype="primary" @click="confirm"> determine < / el - button > < / div > < / el - dialog > < / div > < / template >Copy the code
- Simulation data data part:
data() {
return {
listData: [
{
id: 1,
name: 'syz',
sex: 'male',
auth: [1, 2]
},
{
id: 2,
name: 'lyy',
sex: 'woman',
auth: [11, 21]
},
{
id: 3,
name: 'yf',
sex: 'male',
auth: [211, 212]
},
{
id: 4,
name: 'xkl',
sex: 'woman',
auth: [211]
},
{
id: 5,
name: 'txl',
sex: 'woman',
auth: [221]
}
],
dialogVisible: false,
treeData: [
{
id: 1,
label: 'level 1',
children: [
{
id: 11,
label: 'secondary 1-1'
},
{
id: 12,
label: 'secondary 1-2'
}
]
},
{
id: 2,
label: 'level 2',
children: [
{
id: 21,
label: 'secondary 2-1',
children: [
{
id: 211,
label: 'triple the 2-1-1'
},
{
id: 212,
label: 'triple the 2-1-2'
}
]
},
{
id: 22,
label: 'secondary 2-2',
children: [
{
id: 221,
label: 'triple the 2-2-1'}]}]}}Copy the code
4. Problem description
Problem a:
- Click Configure Opetation (scope.row.auth), the popup box needs to pop up and set the default permission. Here we check it by id, which needs to be set according to Node-key =”id”.
opetation (auth) {
this.dialogVisible = true
this.$refs.tree.setCheckedKeys(auth)
}
Copy the code
The following error is reported:
vue.esm.js?efeb:591 [Vue warn]: Error in event handler for "click": "TypeError: Cannot read property 'setCheckedKeys' of undefined"I believe many people have encountered this problem because this.dialogVisible =true", the dom is not updated immediately, but is rendered again after the whole logic is executed. Therefore, the popbox is not rendered and does not exist in the DOM tree.$refs.tree is undefinedsetCheckedKeys is definitely undefined. Solution: This.$nextTickThis ().$nextTick() will execute the callback after dom update: opetation (auth) {this.dialogVisible =true
this.$nextTick(function() {
this.$refs.tree.setCheckedKeys(auth)
})
}
Copy the code
Every time you open the popup box, you will get the latest role permissions and check them.
Problem two:
- After obtaining node data, when the parent node is selected, all the child nodes are selected, but in fact, only part of the molecular nodes are selected in many cases.
- Obtain node information by using the check method:
currentChecked(data, currentChecked) { const { checkedNodes, halfCheckedNodes } = currentChecked console.log(checkedNodes, halfCheckedNodes) } Copy the code
- The check method has two parameters: the object corresponding to this node and the current selected object of the tree (including four attributes checkedNodes, checkedKeys, halfCheckedNodes, and halfCheckedKeys). There are three states of a tree node: selected, partially selected, and unselected. CheckedNodes indicates the currently selected node, and halfCheckedNodes indicates the partially selected node (only the parent node has some selected nodes under the parent node).
- Note the status of the selected node:
currentChecked(data, currentChecked) { let auth = [] const { checkedNodes, halfCheckedNodes } = currentChecked halfCheckedNodes.length && halfCheckedNodes.forEach(({ id }) => { auth.push({ id, type: 2 }) }) checkedNodes.length && checkedNodes.forEach(({ id }) => { auth.push({ id, type: 1})}) // API saves auth data to background}Copy the code
- Modify the opetation method and listData data to filter by type and set only the selected nodes (type=1). The parent node will be automatically selected according to the status of the child nodes.
auth: [ { id: 1, type: 1}]Copy the code
opetation (auth) { this.dialogVisible = true const arr = [] auth.length &&auth.map(({ id, type= > {})type === 1 && arr.push(id) }) this.$nextTick(function() { this.$refs.tree.setCheckedKeys(arr) }) } Copy the code
Question 3:
- When we encapsulate the el-Tree into a common component, such as auth-tree, this refers to the encapsulated component in the page.
<auth-tree
ref="authTree"
:show-checkbox="true"
:tree-data="tableTreeData"
@currentChecked="currentChecked"/>
Copy the code
At this time if we use this. $refs. AuthTree. SetCheckedKeys (auth) will still be an error:
vue.esm.js?efeb:591 [Vue warn]: Error in event handler for "click": "TypeError: Cannot read property 'setCheckedKeys' of undefined"
Copy the code
Solution: In the parent component:
click() {
this.$refs.authTree.setCheckedKeys(auth)
}
Copy the code
Add the setCheckedKeys method to the component:
setCheckedKeys(auth) {
this.$refs.tree.setCheckedKeys(auth)
}
Copy the code
5, summary
- Node-key =”id”, which is used to set the node status.
- Callback after this.$nextTick () pops open.
- SetCheckedKeys () must be direct through the ref of the node itself.
- CheckedNodes, halfCheckedNodes, records the different states of several points.
- This article is only for specific scenarios. If you encounter other scenarios, please leave a comment and discuss solutions.