• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

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

武飞扬头像
教练、我想打篮球
帮助1

前言

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

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

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

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

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

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

样例代码

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

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

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

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

学新通

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

学新通

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

学新通

展示效果

增删改查的演示 

学新通

保存 选中状态, 展开状态 

 学新通

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

学新通

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

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

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbfbke
系列文章
更多 icon
同类精品
更多 icon
继续加载