vue怎么用watch实现无限树形,递归选中反选,如下图和代码

问题

  1. 孙级全部选中,对应的父级自动选中,父级全部选中,对应的爷级自动选中....
  2. 兄弟之间互不影响

image.png

<template>
  <div>
    <ul>
      <label>
        <input v-model='checkAll'
               type="checkbox"
               @change='handleCheckAll'>
        全选 {{checkAll}}
      </label>
      <li v-for='item in list'
          :key='item.id'>
        <label>
          <input type="checkbox"
                 @click.stop='handleCheckItem(item)'
                 v-model='item.checked'>
          {{item.label}}---{{item.checked}}
        </label>
        <ul v-if='item.children && item.children.length'>
          <li v-for='item2 in item.children'
              :key='item2.id'
              style='padding-left:20px'>
            <label>
              <input type="checkbox"
                     @click.stop='handleCheckItem(item2)'
                     v-model='item2.checked'>
              {{item2.label}}---{{item2.checked}}
            </label>
            <ul v-if='item2.children && item2.children.length'>
              <li v-for='item3 in item2.children'
                  :key='item3.id'
                  style='padding-left:20px'>
                <label>
                  <input type="checkbox"
                         @click.stop='handleCheckItem(item3)'
                         v-model='item3.checked'>
                  {{item3.label}}---{{item3.checked}}
                </label>
              </li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </div>
</template>
<script>
export default {
  name: 'checkbox',
  methods: {
    handleCheckAll (e) {
      if (e.target.checked === true) {
        this.data.forEach(item => {
          this.$set(item, 'checked', true)
        })
      } else {
        this.data.forEach(item => {
          this.$set(item, 'checked', false)
        })
      }
    },
    handleCheckItem (e) {
      // console.log(e)
    }
  },
  watch: {
    'list.children': {
      handler (oldVal, newVal) {
        if (oldVal) {
          var isBoolean = newVal.every(item => {
            console.log(item.checkAll)
          })
          console.log(isBoolean)
        }
      },
      deep: true
    }
  },
  data () {
    return {

      list: [
        {
          label: "一级 1",
          id: 1,
          checked: false,
          children: [
            {
              label: "二级 1-1",
              id: 2,
              checked: false,
              children: [
                {
                  id: 3,
                  label: "三级 1-1-1",
                  checked: false,
                }
              ]
            }
          ]
        },
        {
          label: "一级 2",
          id: 4,
          checked: false,
          children: [
            {
              id: 5,
              label: "二级 2-1",
              checked: false,
              children: [
                {
                  id: 6,
                  label: "三级 2-1-1",
                  checked: false,
                }
              ]
            },
            {
              id: 7,
              label: "二级 2-2",
              checked: false,
              children: [
                {
                  id: 8,
                  label: "三级 2-2-1",
                  checked: false,
                }
              ]
            }
          ]
        },
        {
          label: "一级 3",
          id: 9,
          checked: false,
          children: [
            {
              id: 10,
              label: "二级 3-1",
              checked: false,
              children: [{ id: 11, label: "三级 3-1-1", checked: false, }]
            },
            {
              id: 12,
              label: "二级 3-2",
              checked: false,
              children: [
                {
                  id: 13,
                  label: "三级 3-2-1",
                  checked: false,
                },
                {
                  id: 14,
                  label: "三级 3-2-2",
                  checked: false,
                }
              ]
            }
          ]
        }
      ]
    }
  },
}
</script>
阅读 3k
1 个回答
新手上路,请多包涵

简单一点的话,你可以引入ui库,用组件,简单暴力。安利下element-ui和ivew的tree组件,也就是你所要的需求。https://element.eleme.cn/#/zh...
当然也是可以自己完善的,我也做过类似的,你可以参考下下面代码的思路,比如递归思路

      //点击复选框
      clickBox(data){
        var checkedNodesArr = this.$refs.tree.getCheckedNodes();
        let state = !!checkedNodesArr.find(item => item.id == data.id);
        // 处理点击含有子菜单的复选框时,把子菜单一起勾选或者一起取消勾选状态
        this.clickTreeData(data, state);
        // 处理点击子菜单时,若勾选时其父级以及祖级也要显勾选状态,不勾选即不用处理
        if (!!checkedNodesArr.find(item => item.id == data.id)) {
          this.checkTreeParents(data.pId);
        }
      },
      clickTreeData(data, state){
        let arr= this.getArr(data);
        //获取已勾选的所有数组
        var checkedNodesArr = this.$refs.tree.getCheckedNodes();
        arr.forEach((item)=>{
          if (state == false && checkedNodesArr.find(v => v.id == item.id)) {
            //若本来就在勾选的数组里,就将其移除
            checkedNodesArr.splice(checkedNodesArr.findIndex(v => v.id == item.id), 1);
          } else if (state == true && !checkedNodesArr.find(v => v.id == item.id)) {
            checkedNodesArr.push(item);
          }
        })
        this.$refs.tree.setCheckedNodes(checkedNodesArr);
      },
      getArr(obj){
        return [
          obj,
          ...obj.children.map(item => this.getArr(item)),
        ].flat(Infinity);
      },
      checkTreeParents(pid){
        let retArr = this.originalData.find(v => v.id == pid);
        var checkedNodesArr = this.$refs.tree.getCheckedNodes();
        if (!!retArr && !checkedNodesArr.find(v => v.id == retArr.id)) {
          checkedNodesArr.push(retArr);
          this.$refs.tree.setCheckedNodes(checkedNodesArr);
          this.checkTreeParents(retArr.pId);
        }
      },
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题