16 el-tree 保存树的 选择状态, 展开状态
Posted 蓝风9
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了16 el-tree 保存树的 选择状态, 展开状态相关的知识,希望对你有一定的参考价值。
前言
需求 来自于一些实际的场景
这里 仅仅是一个 样例来实现 这一部分需求
这部分 处理也相对比较简单, 就直接 展示 代码了
1. 节点 增删改查 的实现(一种基于模型的实现, 一种基于 el-tree api 的实现)
2. 保存 el-tree 的 选择状态
3. 保存 el-tree 的 展开状态
样例代码
如下 增删改查两种实现方式, 注释掉的是基于 el-tree 的 api 的使用
<template>
<div>
<div style="width: 20%; float: left;">
(\\#-_-)\\┯━┯
</div>
<div style="width: 20%; float: left;">
<el-tree
ref="treeRef"
:data="tree.nodeList"
show-checkbox
node-key="id"
:default-checked-keys="tree.defaultCheckedKeys"
:default-expanded-keys="tree.defaultExpandedKeys"
:check-on-click-node="true"
:props="tree.defaultProps"
@node-expand="handleNodeExpand"
@node-collapse="handleNodeCollapse"
/>
</div>
<div style="width: 15%; float: left;">
<span> 新增 </span>
<el-select v-model="newNode.parentId" filterable placeholder="请选择父节点">
<el-option v-for="item in treeNodeList" :key="item.id" :label="item.name" :value="item.id"/>
</el-select>
<el-input placeholder="please input id" v-model="newNode.id">
<template slot="prepend">key</template>
</el-input>
<el-input placeholder="please input name" v-model="newNode.name">
<template slot="prepend">name</template>
</el-input>
<el-button @click="handleNewNode">提交</el-button>
</div>
<div style="width: 15%; float: left;">
<span> 更新 </span>
<el-select v-model="updateNode.id" filterable placeholder="请选择节点">
<el-option v-for="item in treeNodeList" :key="item.id" :label="item.name" :value="item.id"/>
</el-select>
<el-input placeholder="please input name" v-model="updateNode.name">
<template slot="prepend">name</template>
</el-input>
<el-button @click="handleUpdateNode">提交</el-button>
</div>
<div style="width: 15%; float: left;">
<span> 移除 </span>
<el-select v-model="removeNode.id" filterable placeholder="请选择节点">
<el-option v-for="item in treeNodeList" :key="item.id" :label="item.name" :value="item.id"/>
</el-select>
<el-button @click="handleRemoveNode">提交</el-button>
</div>
</div>
</template>
<script>
export default
name: 'ElTreeCrud',
computed:
treeNodeList: function ()
let collector = []
this.collectNodeRecursed(this.tree.nodeList, collector)
return collector
,
data ()
return
newNode:
parentId: 'backend',
id: '',
name: '',
,
updateNode:
id: 'backend',
name: '',
,
removeNode:
id: 'backend',
,
tree:
nodeList: [
id: 'backend',
name: '后端',
children: [
id: 'backend1',
name: '后端1',
children: []
,
id: 'backend2',
name: '后端2',
children: []
]
,
id: 'frontend',
name: '前端',
children: [
id: 'frontend1',
name: '前端1',
children: []
,
id: 'frontend2',
name: '前端2',
children: []
]
,
id: 'preprocess',
name: '数据',
children: [
id: 'preprocess1',
name: '数据1',
children: []
,
id: 'preprocess2',
name: '数据2',
children: []
]
],
defaultExpandedKeys: [],
defaultCheckedKeys: ['backend1', 'preprocess1'],
defaultProps:
children: 'children',
label: 'name'
,
mounted ()
window.addEventListener('beforeunload', e => this.beforeLeaveFunc(e))
this.tree.defaultExpandedKeys = this.treeNodeList.map(ele => ele.id)
// check if already stored
// todo, if defaultCheckedKeys is not blank at data's init, then specified node will always be checked
let treeNodeCheckedKeysStr = sessionStorage.getItem('treeNodeCheckedKeys')
if (treeNodeCheckedKeysStr)
this.tree.defaultCheckedKeys = JSON.parse(treeNodeCheckedKeysStr)
// JSON.parse(treeNodeCheckedKeysStr).forEach(ele => this.tree.defaultCheckedKeys.push(ele))
let expandedKeysStr = sessionStorage.getItem('expandedKeys')
if (expandedKeysStr)
this.tree.defaultExpandedKeys = JSON.parse(expandedKeysStr)
,
created ()
,
methods:
// beforeLeaveFunc
beforeLeaveFunc ()
let treeRef = this.$refs.treeRef
let checkedKeys = treeRef.getCheckedKeys()
sessionStorage.removeItem('treeNodeCheckedKeys')
sessionStorage.setItem('treeNodeCheckedKeys_tmp', JSON.stringify(checkedKeys))
if (checkedKeys.length > 0)
sessionStorage.setItem('treeNodeCheckedKeys', JSON.stringify(checkedKeys))
// let treePropRoot = treeRef.root
// let expandedKeys = []
// this.expandedKeys(treePropRoot, expandedKeys)
// sessionStorage.removeItem('expandedKeys')
// sessionStorage.setItem('expandedKeys_tmp', JSON.stringify(expandedKeys))
// if(expandedKeys.length > 0)
// sessionStorage.setItem('expandedKeys', JSON.stringify(expandedKeys))
//
,
// curd
handleNewNode ()
if (!this.newNode.id || !this.newNode.name)
this.$message.error('please input id and name')
return
let targetNode = this.lookUpNode(this.tree.nodeList, this.newNode.id)
if (targetNode)
this.$message.error('update node\\'s with id ' + this.newNode.id + ' already exists')
return
let newNode =
id: this.newNode.id,
name: this.newNode.name,
children: []
// let treeRef = this.$refs.treeRef
// treeRef.append(newNode, treeRef.getNode(this.newNode.parentId))
// this.$message.success(' add new node ' + this.newNode.name + ' at parentNode ' + this.lookUpNode(this.tree.nodeList, this.newNode.parentId).name + ' success')
let parentNode = this.lookUpNode(this.tree.nodeList, this.newNode.parentId)
parentNode.children.push(newNode)
,
handleUpdateNode ()
if (!this.updateNode.id || !this.updateNode.name)
this.$message.error('please input id and name')
return
let targetNode = this.lookUpNode(this.tree.nodeList, this.updateNode.id)
if (!targetNode)
this.$message.error('update node\\'s with id ' + this.newNode.id + ' does not exists')
return
// let treeRef = this.$refs.treeRef
// targetNode.name = this.updateNode.name
// treeRef.updateKeyChildren(this.updateNode.id, targetNode)
targetNode.name = this.updateNode.name
,
handleRemoveNode ()
// let treeRef = this.$refs.treeRef
// let targetNode = this.lookUpNode(this.tree.nodeList, this.removeNode.id)
// if (!targetNode)
// this.$message.error('update node\\'s with id ' + this.removeNode.id + ' does not exists')
// return
//
// treeRef.remove(targetNode)
let parentNode = this.lookUpParentNode(this.tree.nodeList, null, this.removeNode.parentId)
let idxOfNode = parentNode.children.map(ele => ele.id).indexOf(this.removeNode.id)
parentNode.children.splice(idxOfNode, 1)
,
handleNodeExpand (node, nodeProp, treeNode)
console.log('handleNodeExpand')
let treeRef = this.$refs.treeRef
let treePropRoot = treeRef.root
let expandedKeys = []
this.expandedKeys(treePropRoot, expandedKeys)
sessionStorage.removeItem('expandedKeys')
sessionStorage.setItem('expandedKeys_tmp', JSON.stringify(expandedKeys))
if (expandedKeys.length > 0)
sessionStorage.setItem('expandedKeys', JSON.stringify(expandedKeys))
,
handleNodeCollapse (node, nodeProp, treeNode)
// update current node's expand
nodeProp.expanded = false
this.handleNodeExpand(node, nodeProp, treeNode)
,
// assist methods
collectNodeRecursed (nodeList, collector)
if (!nodeList)
return null
for (let idx in nodeList)
let childNode = nodeList[idx]
collector.push(id: childNode.id, name: childNode.name)
if (childNode.children)
this.collectNodeRecursed(childNode.children, collector)
,
lookUpNode (nodeList, id)
if (!nodeList)
return null
for (let idx in nodeList)
let childNode = nodeList[idx]
if (id === childNode.id)
return childNode
if (childNode.children)
let result = this.lookUpNode(childNode.children, id)
if (result)
return result
return null
,
lookUpParentNode (nodeList, parentNode, id)
if (!nodeList)
return null
for (let idx in nodeList)
let childNode = nodeList[idx]
if (id === childNode.id)
if (!parentNode)
parentNode =
children : this.tree.nodeList
return parentNode
if (childNode.children)
let result = this.lookUpParentNode(childNode.children, childNode, id)
if (result)
return result
return null
,
expandedKeys (nodeFromRef, collector)
if (nodeFromRef.expanded)
collector.push(nodeFromRef.data.id)
// 如果不是 root 节点, 并且没有展开, 不继续处理
if ((nodeFromRef.id !== 0) && (!nodeFromRef.expanded))
return
if (nodeFromRef.childNodes)
for (let idx in nodeFromRef.childNodes)
let childNode = nodeFromRef.childNodes[idx]
this.expandedKeys(childNode, collector)
</script>
<!-- Add 'scoped' attribute to limit CSS to this component only -->
<style scoped>
</style>
选中状态, 展开状态 的持久化和初始化
刷新页面的时候 保存选中状态
节点展开/收缩的时候 保存展开状态
初始化的时候 初始化 选中状态, 展开状态
展示效果
增删改查的演示
保存 选中状态, 展开状态
我们看一下 sessionStorage 中存放的 expandedKeys, chekcedKeys 的数据, 是没有问题的
刷新之后的状态, 可以看到这里 "后端1" 的状态是没有保存下来的, 这是另外的一个问题
这个我们下一个文章 再来讲解, 需要 调试到 element 的代码
完
以上是关于16 el-tree 保存树的 选择状态, 展开状态的主要内容,如果未能解决你的问题,请参考以下文章
17 el-tree defaultCheckedKeys配置 和 树上面选中节点不同步问题
17 el-tree defaultCheckedKeys配置 和 树上面选中节点不同步问题