需求 来自于一些实际的场景
这里 仅仅是一个 样例来实现 这一部分需求
这部分 处理也相对比较简单, 就直接 展示 代码了
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)
- }
- }
- }
- }
- }
刷新页面的时候 保存选中状态
节点展开/收缩的时候 保存展开状态
初始化的时候 初始化 选中状态, 展开状态
增删改查的演示
保存 选中状态, 展开状态
我们看一下 sessionStorage 中存放的 expandedKeys, chekcedKeys 的数据, 是没有问题的
刷新之后的状态, 可以看到这里 "后端1" 的状态是没有保存下来的, 这是另外的一个问题
这个我们下一个文章 再来讲解, 需要 调试到 element 的代码
完