zoukankan      html  css  js  c++  java
  • elementui tree回显节点半选解决方案

    问题分析
    前端开发告诉我说【tree组件因为存了后台存储了全部的节点,页面回显时,因为父节点的关系,把子节点也全部勾上了,现在没法处理,必须要改接口加上半选节点的参数保存起来,再在回显时调用接口获取到半选的节点】。

    不得不说,这的确是一个解决方案,但并不是一个好的解决方案。该接口固然能实现这个需求,但是要知道接口的改动会带来一系列意想不到的变化,比如数据库,缓存,接口参数和返回值,而且在已经集成好的接口上拓展新的变化,根据螺旋式开发规则的风险变化,BUG会随着螺旋的增大而急剧增大。虽然这个问题比较小,只是多存储了一些Service端用不上属性而已,但只是因为组件升级或bug,就需要改动功能无问题的接口,这并不是好的开发模式。作为一名优秀的开发者,首先想到的是应该用自己的办法去解决对接的问题,如果实在没有办法,再考虑两端协调的修改。

    从业务分析来看 Service不论是check还是halfCheck都是必要的数据。但view端需要区分check,halfCheck来显示不同的图标,这就很矛盾了,可目的也很明确前端需要区分出半选节点。

    那么怎么改才是最合理的呢?当然是利用JS处理回显的逻辑,这样即使组件变化或BUG依旧不会去改变接口。如果通过改接口修正好了,那若控件升级或bug,难道还要一改再改接口吗,当然不能。接口的设计不可能满足所有组件的需求,但它一定满足业务。既然可以通过自己控制,就没有必要去做一些更繁琐的工作,不是吗?

    废话不多说了,下面看代码!

    解决方案

    new Vue({
    	el: '#app',
    	data: function() {
    		return {
    			data: [{
    				id: "1",
    				label: '1',
    				children: [{
    					id: "2",
    					label: '2-1',
    					children: [{
    						id: "21",
    						label: '2-1-1'
    					}, {
    						id: "22",
    						label: '2-1-2'
    					}]
    				}, {
    					id: "3",
    					label: '2-2',
    					children: [{
    						id: "31",
    						label: '2-2-1'
    					}, {
    						id: "32",
    						label: ' 2-2-2'
    					}]
    				}]
    			}],
    			checkStrictly: true,
    			defaultProps: {
    				children: 'children',
    				label: 'label'
    			}
    		}
    	},
    	mounted() {
        var that = this;
        ["1", "2", "22", "3", "31","32"].forEach((i,n) => {
          var node = that.$refs.menuListTree.getNode(i);
          console.log(node.isLeaf)
          if(node.isLeaf){
            that.$refs.menuListTree.setChecked(node, true);
          }
        });
    	}
    });
    

      


    实现原理
    利用tree组件渲染后带有的isLeaf(是否为叶子节点)属性,如果为叶子节点就选中。这样利用tree的API就实现了正确的回显效果。并没有过多的逻辑,只是利用tree本身的API 出BUG的概率也不会变高。手动设置node其实和prop的default-checked-keys原理是一样的,其实内部也都是循环,也不会出现效率的问题。所处理的也只是多了一层isLeaf的判断而已。

    总结
    我走过的弯路
    看到的第一反应是之前遇到过,早些年在做ztree的时候也有这个问题,当时用API就解决了,el-tree应该也有。于是查了一大圈,发现有个函数叫setCheckedKeys(keys, leafOnly),设置leafOnly = false,就可以只设置子节点选中。以为有用,于是试了一下,发现果然是【子节点】选中啊…父节点一个都没选,于是失败了。
    又找到一个属性叫做 check-strictly,设置check-strictly = true,赋值结束后再重置check-strictly = false表面上看起来是好试了,但仔细点看发现【父节点】不是半选的!!!又失败了…
    说心里话,这点其实el-tree可能可以优化一下会更好,这个需求早在jquery的阶段就有了,ztree就解决过。el做为更新的vue组件,应该早就能设想到这种情况了,但却没有提供回显半选这样的设置属性或者函数,这也是美中不足的地方。

    可爱的地方是即使如此,依然通过API的函数组合,可以达到想要的效果,虽然看起来不是特别优雅,好在没有花太多力气。

    如果一个问题困扰自己很久,有几种可能:

    API了解不够深入,并不熟练
    走了弯路还不肯放弃,非要一条路走到黑,掉入自己画的圈中无法跳出
    确实无法通过现有的方法实现
    正确的解决问题的方式是应该灵活多变的,开发更多的提倡解耦,面向对象,而不是面向过程。就好比考试的时候遇到一个问题,答案可能有很多种。但再多的答案,都需要自己作答,而并不是去修改题目、添加条件,当然若题目出错了自然另当别论。答案的好坏才会关系到得分的高低,再多字数,再华丽的词汇,却没有得分点,那依旧是不得分的。

    就我自己而言,也经常一条路跑到黑,很容易掉进坑里。一般这时候会选择仔细的查API和代码,终会有所发现。要么就换思路,要么就换组件。引用一句不知道谁说的话“妄图用代码解决一切问题的人,最终都会失败。”因为你所使用的库,不可能全部是自己写的,总会有自己的逻辑无法触及的地方,难道遇到一个就要改一份源码吗?当然不能。^_^

  • 相关阅读:
    docker 容器简单使用
    C++ | 程序编译连接原理
    C++ | 虚拟地址空间
    python学习笔记(十)——进程间通信
    菜鸟教程-c
    现代操作系统-第三版-疑问
    小米C++面经
    面经积累-杂
    哈希表相关题目-leetcode简单
    字符串相关题目-leetcode简单(6-10/共51道)
  • 原文地址:https://www.cnblogs.com/adjk/p/14968409.html
Copyright © 2011-2022 走看看