iview组件库:自定义方法去控制Tree树形数据的根节点与叶节点的关联性

1、问题描述:

今天会议上针对权限提出了新的意见,权限需要控制到按钮级别,意味着不同的用户可能拥有相同的页面的查看权限,但是有的用户能使用里面的按钮权限,比如:新增项目,编辑产品....等按钮功能,但是有的用户不能去使用里面的按钮权限功能。

2、后台数据返回:

后台将数据加在页面的children下,如图,这一层级就是按钮权限的控制,我前端这边就是需要根据checked的布尔值去控制。一开始我是直接使用tree树形组件去渲染,然后就感觉做完了,直到测试提出几个问题点。


image.png

3、直接使用tree树形组件去渲染带来的问题点:

  • 1、按钮权限的勾选应与页面区分开:比如(该用户可能没有所有的按钮权限使用,但是可以查看这个页面,而树形组件使用了父节点与子节点相关联的话,那么子节点全部去掉勾选,父节点也会相应的去掉勾选的!)
  • 2、将树形组件改为父子节点不相关联,依旧存在问题,比如(父子节点不相关联,但是需求所要的是父节点取消勾选,其下的所有子节点应该同样的取消勾选!)

4、需求整理:

发现了问题点,大概将问题整理了一下:
1、选中当前按钮权限层级的节点或者取消勾选当前页码下的所有的按钮权限层级的节点,它的父节点的勾选状态应该不发生改变。
2、但是当这个父节点的页面没有权限的时候,按钮的权限应该对应的也全部没有。
3、控制页面查看权限的父节点如果也取消了勾选,那么页面的查看权限以及下面所有的按钮查看权限也应该全部取消
4、如果页面没有查看权限,不能去给用户分配按钮的查看权限

大致的效果图展示:
权限分配树形.gif

5、iview官网的API

API.png

6、代码部分:

6.1、方法一:根据当前所有已勾选的数组去处理(比较麻烦!)

1、先获取后台接口数据渲染到树形组件上去
    getdata() {
      getResource(this.roleId).then((res) => {
        if (res.code == 0) {
          this.datalist = res.data;
        }
      });
    },
2、在树形组件上添加父子节点不相关联的属性以及渲染数据
    <Tree
      :data="datalist"
      :check-strictly="true"
      @on-select-change="handleCheckChange"
      @on-check-change="handleSelectChange"
      show-checkbox
      multiple
      ref="tree"
    ></Tree>
    <div slot="footer" class="dialog-footer">
      <Button @click="cancel()">取消</Button>
      <Button type="primary" @click="confirm()">确定</Button>
    </div>
3、在Vue原型对象上拓展两个后面需要用到的方法
  created() {
    // 添加数组删除的方法
    Array.prototype.remove = function (arr, val) {
      const newArr = [];
      arr.forEach((item) => {
        if (item !== val) {
          newArr.push(item);
        }
      });
      return newArr;
    };
    // 添加两个数组对比的方法
    Array.prototype.select = function (allArr, partArr) {
      for (let i = allArr.length - 1; i >= 0; i--) {
        for (let j = 0; j < partArr.length; j++) {
          if (allArr[i].id === partArr[j].id) {
            allArr.splice(i, 1);
            break;
          }
        }
      }
      return allArr;
    };
  },
4、对数据进行处理,筛选所有的根节点(即parentId为0的节点)
    // 封装查找parentId为0的节点
    getParent(arr) {
      this.treeData = [];
      let list = arr.map((item) => {
        if (item.children) {
          return {
            ...item,
          };
        }
      });
      let dataTree = list.remove(list, undefined);
      for (var i = 0; i < dataTree.length; i++) {
        // 将所有的parentId为0的整理到一起
        if (dataTree[i].parentId == "0") {
          this.treeData.push(dataTree[i]);
        }
      }
      return this.treeData;
    },
5、让下面的第一层级的子节点跟随着父节点的布尔值,但是注意:只跟随checked=false的时候
    // 遍历数组,让下面的第一层的子节点checked值跟随父节点走
    refreshSonNode(arr) {
      arr.forEach((item) => {
        if (item.checked) {
          // console.log("item的checked: ", item.checked);
        } else {
          console.log("item的checked: ", item.checked);
          item.children.forEach((el) => {
            if (el.checked) {
              el.checked = false;
            }
            if (el.children) {
              el.children.forEach((obj) => {
                if (obj.checked) {
                  obj.checked = false;
                }
              });
            }
          });
        }
      });
    },
6、开始对点击树形组件的复选框进行处理

API中明确的说明了返回的是当前已经勾选的数组、当前项。

    // 点击获取所有选中节点
    handleSelectChange(val) {
      if (this.getParent(val).length < this.datalist.length) {
        // 长度比后台返回的还小,就表示做了取消操作
        this.originTree = this.getParent(this.datalist);
        this.parentId = this.getParent(val);
        // 筛选出parentId为0的数组的差异
        let currNode = this.originTree.select(this.originTree, this.parentId);
        // 刷新第一级的子节点value
        this.refreshSonNode(currNode);
        this.parentId.forEach(item=>{
          if(item.checked){
            // 为true则再去判断它的子级
            if(item.children){
              this.refreshSonNode(item.children);
            }
          }
        })
      } else {
        // 否则新增的话直接渲染val的所有节点
        this.refreshSonNode(this.getParent(val));
      }
    },
7、提交数据(已勾选的节点id)
this.list = this.$refs.tree.getCheckedAndIndeterminateNodes();
let data = [];
this.list.forEach((item) => {
  data.push(item.id);
});

这种方法比较繁琐,谨慎选择。

6.1、方法二:根据点击选中的当前项去处理(比较简单)

这种方法只需要在点击的时候去做判断处理就OK了,不需要进行大量的数据逻辑筛选处理。

1、封装遍历方法,我这项目权限最高到按钮权限,所以就没用递归方法了
    DealSonNode(arr){
      if(!arr.checked && arr.children){
        // 当前项的checked值非真,并且它下面有子节点
        arr.children.forEach(item=>{
          item.checked = false;
          if(item.children){
            item.children.forEach(el=>{
              el.checked = false;
            })
          }
        })
      }
    },
2、点击事件的处理
// 获取当前项数据
handleSelectChange(val,vcasl) {
   this.DealSonNode(vcasl);
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355

推荐阅读更多精彩内容