vue3 两级树列表效果

vue yekong

vue3 两级树列表,父节点可以展开收缩 可以全选和取消全选 子节点可以选中 子节点全部选择后父节点自动选择

可以按照以下步骤进行操作:

  1. 在Vue组件中,创建一个包含树的数据的数组,每个节点包含id、label、selected、expanded和children属性。
  2. 在模板中使用v-for指令循环渲染树的节点,并根据节点的属性绑定选择状态、展开状态和相应的事件处理程序。
  3. 实现展开收缩功能:为了实现节点的展开和收缩,你可以使用节点的expanded属性来表示节点是否展开。通过点击展开收缩的图标或按钮时,切换节点的expanded属性的值。
  4. 实现全选和取消全选功能:在父节点上添加一个复选框,用于全选和取消全选子节点。通过v-model指令将该复选框与全选状态绑定,并在变化时更新所有节点的选择状态。
  5. 实现子节点全部选择后父节点自动选择的行为:通过监听子节点选择状态的变化,在所有子节点都被选择时,自动将父节点的选择状态设置为选中。

下面是一个示例的代码片段,演示了如何在一个Vue组件中实现上述功能:

vue3 两级树列表效果

/**
* @Author: 858834013@qq.com
* @Name: item1
* @Date: 2023年06月28日14:30:09
* @Desc:
*/
<template>
  <div class="container">
    <div class="search">
      <input type="text" placeholder="请选择设备">
      <img src="./assets/icon_search.png" alt="">
    </div>
    <div class="tree">
      <ul>
        <li v-for="node in treeData" :key="node.id">
          <div class="titleInfo">
            <div class="zhankai" @click="toggleExpand(node)">
              <img v-if="node.expanded" src="./assets/icon_zhankai.png" alt="">
              <img v-else src="./assets/icon_shousuo.png" alt="">
            </div>
            <selected v-model:expanded="node.selected" @change="checkChildren(node)"></selected>
            <div class="shexiangtou">
              <img src="./assets/icon_shexiangtou.png" alt="">
            </div>
            <span @click="toggleExpand(node)">{{ node.label }}</span>
          </div>
          <ul v-show="node.expanded">
            <li v-for="child in node.children" :key="child.id">
              <div class="titleInfo">
                <selected v-model:expanded="child.selected" @change="checkParent(node)"></selected>
                <div class="shexiangtou">
                  <img src="./assets/icon_shexiangtou.png" alt="">
                </div>
                <span @click="child.selected=!child.selected">{{ child.label }}</span>
              </div>
            </li>
          </ul>
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import selected from "./selected.vue";

export default {
  name: 'item1s',
  data() {
    return {
      treeData: [
        {
          id: 1,
          label: 'Parent 1',
          selected: false,
          expanded: false,
          children: [
            {
              id: 2,
              label: 'Child 1-1',
              selected: false
            },
            {
              id: 3,
              label: 'Child 1-2',
              selected: false
            }
          ]
        }
      ]
    };
  },
  components: {selected},
  computed: {
    selectAll: {
      get() {
        return this.treeData.every(node => node.selected);
      },
      set(value) {
        this.treeData.forEach(node => {
          node.selected = value;
        });
      }
    }
  },
  methods: {
    toggleExpand(parent) {
      parent.expanded = !parent.expanded;
    },
    checkChildren(parent) {
      parent.children.forEach(child => {
        child.selected = parent.selected;
      });
    },
    checkParent(parent) {
      parent.selected = parent.children.every(child => child.selected);
    },
    selectAllNodes() {
      if (this.selectAll) {
        this.treeData.forEach(parent => {
          parent.selected = false;
          parent.children.forEach(child => {
            child.selected = false;
          });
        });
      } else {
        this.treeData.forEach(parent => {
          parent.selected = true;
          parent.children.forEach(child => {
            child.selected = true;
          });
        });
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.container {
  width: calc(100% - 40px);
  height: calc(100% - 40px);
  position: relative;
  margin: 0 auto;

  .search {
    width: 100%;
    height: 38px;
    background: url("./assets/searchbg.png") no-repeat;
    background-size: 100% 100%;
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: nowrap;
    flex-direction: row;
    align-content: flex-start;

    input {
      background: none;
      width: calc(100% - 12px);
      outline: none;
      border: none;
      position: relative;
      height: calc(100% - 3px);
      color: #fff;
      margin-left: 12px;
    }

    /* 标准写法 */
    input::placeholder {
      color: rgba(126, 175, 236, 1);
    }

    /* WebKit 内核浏览器(Chrome、Safari) */
    input::-webkit-input-placeholder {
      color: rgba(126, 175, 236, 1);
    }

    /* Internet Explorer 浏览器 */
    input:-ms-input-placeholder {
      color: rgba(126, 175, 236, 1);
    }

    img {
      width: 16px;
      height: 16px;
      margin-right: 14px;
      flex-shrink: 0;
    }
  }
}

.tree {
  width: 100%;
  position: relative;
  height: calc(100% - 300px);

  ul {
    list-style-type: none;
    font-size: 14px;
    font-family: MiSans;
    font-weight: 400;
    color: #FFFFFF;
  }
}

.titleInfo {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  flex-wrap: nowrap;
  flex-direction: row;
  align-content: flex-start;
  height: 45px;
  cursor: pointer;
}

.shexiangtou {
  width: 34px;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: nowrap;
  flex-direction: row;
  align-content: flex-start;

  img {
    width: 14px;
  }
}

.zhankai {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  flex-wrap: nowrap;
  flex-direction: row;
  align-content: flex-start;

  img {
    margin-right: 10px;
  }
}
</style>

在这个示例中,我们通过使用v-for指令循环渲染父节点和子节点,然后使用v-model指令实现选择状态的双向绑定。我们还添加了一些方法来处理展开、选择和全选的逻辑。最后,我们使用计算属性来获取全选状态,并在全选复选框上使用v-model指令实现全选和取消全选的功能。

文件下载

相关文件下载地址
此资源需支付 ¥1 后下载
支付宝购买扫右侧红包码购买更优惠,如无法下载请联系微信:17331886870
喜欢
vue3 两级树列表效果