• 16 el-tree 保存树的 选择状态, 展开状态


    前言

    需求 来自于一些实际的场景 

    这里 仅仅是一个 样例来实现 这一部分需求 

    这部分 处理也相对比较简单, 就直接 展示 代码了 

    1. 节点 增删改查 的实现(一种基于模型的实现, 一种基于 el-tree api 的实现)

    2. 保存 el-tree 的 选择状态 

    3. 保存 el-tree 的 展开状态 

    样例代码

    如下 增删改查两种实现方式, 注释掉的是基于 el-tree 的 api 的使用 

    1. <template>
    2. <div>
    3. <div style="width: 20%; float: left;">
    4. (\#-_-)\┯━┯
    5. </div>
    6. <div style="width: 20%; float: left;">
    7. <el-tree
    8. ref="treeRef"
    9. :data="tree.nodeList"
    10. show-checkbox
    11. node-key="id"
    12. :default-checked-keys="tree.defaultCheckedKeys"
    13. :default-expanded-keys="tree.defaultExpandedKeys"
    14. :check-on-click-node="true"
    15. :props="tree.defaultProps"
    16. @node-expand="handleNodeExpand"
    17. @node-collapse="handleNodeCollapse"
    18. />
    19. </div>
    20. <div style="width: 15%; float: left;">
    21. <span> 新增 </span>
    22. <el-select v-model="newNode.parentId" filterable placeholder="请选择父节点">
    23. <el-option v-for="item in treeNodeList" :key="item.id" :label="item.name" :value="item.id"/>
    24. </el-select>
    25. <el-input placeholder="please input id" v-model="newNode.id">
    26. <template slot="prepend">key</template>
    27. </el-input>
    28. <el-input placeholder="please input name" v-model="newNode.name">
    29. <template slot="prepend">name</template>
    30. </el-input>
    31. <el-button @click="handleNewNode">提交</el-button>
    32. </div>
    33. <div style="width: 15%; float: left;">
    34. <span> 更新 </span>
    35. <el-select v-model="updateNode.id" filterable placeholder="请选择节点">
    36. <el-option v-for="item in treeNodeList" :key="item.id" :label="item.name" :value="item.id"/>
    37. </el-select>
    38. <el-input placeholder="please input name" v-model="updateNode.name">
    39. <template slot="prepend">name</template>
    40. </el-input>
    41. <el-button @click="handleUpdateNode">提交</el-button>
    42. </div>
    43. <div style="width: 15%; float: left;">
    44. <span> 移除 </span>
    45. <el-select v-model="removeNode.id" filterable placeholder="请选择节点">
    46. <el-option v-for="item in treeNodeList" :key="item.id" :label="item.name" :value="item.id"/>
    47. </el-select>
    48. <el-button @click="handleRemoveNode">提交</el-button>
    49. </div>
    50. </div>
    51. </template>
    52. <script>
    53. export default {
    54. name: 'ElTreeCrud',
    55. computed: {
    56. treeNodeList: function () {
    57. let collector = []
    58. this.collectNodeRecursed(this.tree.nodeList, collector)
    59. return collector
    60. }
    61. },
    62. data () {
    63. return {
    64. newNode: {
    65. parentId: 'backend',
    66. id: '',
    67. name: '',
    68. },
    69. updateNode: {
    70. id: 'backend',
    71. name: '',
    72. },
    73. removeNode: {
    74. id: 'backend',
    75. },
    76. tree: {
    77. nodeList: [{
    78. id: 'backend',
    79. name: '后端',
    80. children: [
    81. {
    82. id: 'backend1',
    83. name: '后端1',
    84. children: []
    85. }, {
    86. id: 'backend2',
    87. name: '后端2',
    88. children: []
    89. }
    90. ]
    91. }, {
    92. id: 'frontend',
    93. name: '前端',
    94. children: [
    95. {
    96. id: 'frontend1',
    97. name: '前端1',
    98. children: []
    99. }, {
    100. id: 'frontend2',
    101. name: '前端2',
    102. children: []
    103. }
    104. ]
    105. }, {
    106. id: 'preprocess',
    107. name: '数据',
    108. children: [
    109. {
    110. id: 'preprocess1',
    111. name: '数据1',
    112. children: []
    113. }, {
    114. id: 'preprocess2',
    115. name: '数据2',
    116. children: []
    117. }
    118. ]
    119. }],
    120. defaultExpandedKeys: [],
    121. defaultCheckedKeys: ['backend1', 'preprocess1'],
    122. defaultProps: {
    123. children: 'children',
    124. label: 'name'
    125. }
    126. }
    127. }
    128. },
    129. mounted () {
    130. window.addEventListener('beforeunload', e => this.beforeLeaveFunc(e))
    131. this.tree.defaultExpandedKeys = this.treeNodeList.map(ele => ele.id)
    132. // check if already stored
    133. // todo, if defaultCheckedKeys is not blank at data's init, then specified node will always be checked
    134. let treeNodeCheckedKeysStr = sessionStorage.getItem('treeNodeCheckedKeys')
    135. if (treeNodeCheckedKeysStr) {
    136. this.tree.defaultCheckedKeys = JSON.parse(treeNodeCheckedKeysStr)
    137. // JSON.parse(treeNodeCheckedKeysStr).forEach(ele => this.tree.defaultCheckedKeys.push(ele))
    138. }
    139. let expandedKeysStr = sessionStorage.getItem('expandedKeys')
    140. if (expandedKeysStr) {
    141. this.tree.defaultExpandedKeys = JSON.parse(expandedKeysStr)
    142. }
    143. },
    144. created () {
    145. },
    146. methods: {
    147. // beforeLeaveFunc
    148. beforeLeaveFunc () {
    149. let treeRef = this.$refs.treeRef
    150. let checkedKeys = treeRef.getCheckedKeys()
    151. sessionStorage.removeItem('treeNodeCheckedKeys')
    152. sessionStorage.setItem('treeNodeCheckedKeys_tmp', JSON.stringify(checkedKeys))
    153. if (checkedKeys.length > 0) {
    154. sessionStorage.setItem('treeNodeCheckedKeys', JSON.stringify(checkedKeys))
    155. }
    156. // let treePropRoot = treeRef.root
    157. // let expandedKeys = []
    158. // this.expandedKeys(treePropRoot, expandedKeys)
    159. // sessionStorage.removeItem('expandedKeys')
    160. // sessionStorage.setItem('expandedKeys_tmp', JSON.stringify(expandedKeys))
    161. // if(expandedKeys.length > 0) {
    162. // sessionStorage.setItem('expandedKeys', JSON.stringify(expandedKeys))
    163. // }
    164. },
    165. // curd
    166. handleNewNode () {
    167. if (!this.newNode.id || !this.newNode.name) {
    168. this.$message.error('please input id and name')
    169. return
    170. }
    171. let targetNode = this.lookUpNode(this.tree.nodeList, this.newNode.id)
    172. if (targetNode) {
    173. this.$message.error('update node\'s with id ' + this.newNode.id + ' already exists')
    174. return
    175. }
    176. let newNode = {
    177. id: this.newNode.id,
    178. name: this.newNode.name,
    179. children: []
    180. }
    181. // let treeRef = this.$refs.treeRef
    182. // treeRef.append(newNode, treeRef.getNode(this.newNode.parentId))
    183. // this.$message.success(' add new node ' + this.newNode.name + ' at parentNode ' + this.lookUpNode(this.tree.nodeList, this.newNode.parentId).name + ' success')
    184. let parentNode = this.lookUpNode(this.tree.nodeList, this.newNode.parentId)
    185. parentNode.children.push(newNode)
    186. },
    187. handleUpdateNode () {
    188. if (!this.updateNode.id || !this.updateNode.name) {
    189. this.$message.error('please input id and name')
    190. return
    191. }
    192. let targetNode = this.lookUpNode(this.tree.nodeList, this.updateNode.id)
    193. if (!targetNode) {
    194. this.$message.error('update node\'s with id ' + this.newNode.id + ' does not exists')
    195. return
    196. }
    197. // let treeRef = this.$refs.treeRef
    198. // targetNode.name = this.updateNode.name
    199. // treeRef.updateKeyChildren(this.updateNode.id, targetNode)
    200. targetNode.name = this.updateNode.name
    201. },
    202. handleRemoveNode () {
    203. // let treeRef = this.$refs.treeRef
    204. // let targetNode = this.lookUpNode(this.tree.nodeList, this.removeNode.id)
    205. // if (!targetNode) {
    206. // this.$message.error('update node\'s with id ' + this.removeNode.id + ' does not exists')
    207. // return
    208. // }
    209. // treeRef.remove(targetNode)
    210. let parentNode = this.lookUpParentNode(this.tree.nodeList, null, this.removeNode.parentId)
    211. let idxOfNode = parentNode.children.map(ele => ele.id).indexOf(this.removeNode.id)
    212. parentNode.children.splice(idxOfNode, 1)
    213. },
    214. handleNodeExpand (node, nodeProp, treeNode) {
    215. console.log('handleNodeExpand')
    216. let treeRef = this.$refs.treeRef
    217. let treePropRoot = treeRef.root
    218. let expandedKeys = []
    219. this.expandedKeys(treePropRoot, expandedKeys)
    220. sessionStorage.removeItem('expandedKeys')
    221. sessionStorage.setItem('expandedKeys_tmp', JSON.stringify(expandedKeys))
    222. if (expandedKeys.length > 0) {
    223. sessionStorage.setItem('expandedKeys', JSON.stringify(expandedKeys))
    224. }
    225. },
    226. handleNodeCollapse (node, nodeProp, treeNode) {
    227. // update current node's expand
    228. nodeProp.expanded = false
    229. this.handleNodeExpand(node, nodeProp, treeNode)
    230. },
    231. // assist methods
    232. collectNodeRecursed (nodeList, collector) {
    233. if (!nodeList) {
    234. return null
    235. }
    236. for (let idx in nodeList) {
    237. let childNode = nodeList[idx]
    238. collector.push({id: childNode.id, name: childNode.name})
    239. if (childNode.children) {
    240. this.collectNodeRecursed(childNode.children, collector)
    241. }
    242. }
    243. },
    244. lookUpNode (nodeList, id) {
    245. if (!nodeList) {
    246. return null
    247. }
    248. for (let idx in nodeList) {
    249. let childNode = nodeList[idx]
    250. if (id === childNode.id) {
    251. return childNode
    252. }
    253. if (childNode.children) {
    254. let result = this.lookUpNode(childNode.children, id)
    255. if (result) {
    256. return result
    257. }
    258. }
    259. }
    260. return null
    261. },
    262. lookUpParentNode (nodeList, parentNode, id) {
    263. if (!nodeList) {
    264. return null
    265. }
    266. for (let idx in nodeList) {
    267. let childNode = nodeList[idx]
    268. if (id === childNode.id) {
    269. if (!parentNode) {
    270. parentNode = {
    271. children : this.tree.nodeList
    272. }
    273. }
    274. return parentNode
    275. }
    276. if (childNode.children) {
    277. let result = this.lookUpParentNode(childNode.children, childNode, id)
    278. if (result) {
    279. return result
    280. }
    281. }
    282. }
    283. return null
    284. },
    285. expandedKeys (nodeFromRef, collector) {
    286. if (nodeFromRef.expanded) {
    287. collector.push(nodeFromRef.data.id)
    288. }
    289. // 如果不是 root 节点, 并且没有展开, 不继续处理
    290. if ((nodeFromRef.id !== 0) && (!nodeFromRef.expanded)) {
    291. return
    292. }
    293. if (nodeFromRef.childNodes) {
    294. for (let idx in nodeFromRef.childNodes) {
    295. let childNode = nodeFromRef.childNodes[idx]
    296. this.expandedKeys(childNode, collector)
    297. }
    298. }
    299. }
    300. }
    301. }

    选中状态, 展开状态 的持久化和初始化 

    刷新页面的时候 保存选中状态 

    节点展开/收缩的时候 保存展开状态 

    初始化的时候 初始化 选中状态, 展开状态 

    展示效果

    增删改查的演示 

    保存 选中状态, 展开状态 

     

    我们看一下 sessionStorage 中存放的 expandedKeys, chekcedKeys 的数据, 是没有问题的

     刷新之后的状态, 可以看到这里 "后端1" 的状态是没有保存下来的, 这是另外的一个问题 

    这个我们下一个文章 再来讲解, 需要 调试到 element 的代码 

  • 相关阅读:
    红酒:红酒保存的理想温度与湿度
    GBase 8c 备份控制函数(四)
    JavaWeb-三大核心组件(Servlet、Filter、Listener)
    26. 删除有序数组中的重复项-遍历数组
    【软件安装】服务器(docker) 安装 jupyter
    【数据结构】链表C语言编写的,它定义了一个链表,并实现了一些基本的链表操作,如创建新节点、插入节点、清空链表、输出链表以及查找节点
    Spring Cloud 系列:Seata 中TCC模式具体实现
    工厂模式相关总结和使用
    ASEMI快恢复二极管ES8JC参数,ES8JC规格,ES8JC封装
    机器学习基础:奇异值分解(SVD)
  • 原文地址:https://blog.csdn.net/u011039332/article/details/126876149