Bootstrap

[vue3] Tree/TreeSelect树形控件使用

 ✨✨个人主页:沫洺的主页

📚📚系列专栏: 📖 JavaWeb专栏📖 JavaSE专栏 📖 Java基础专栏📖vue3专栏 

                           📖MyBatis专栏📖Spring专栏📖SpringMVC专栏📖SpringBoot专栏

                           📖Docker专栏📖Reids专栏📖MQ专栏📖SpringCloud专栏     

💖💖如果文章对你有所帮助请留下三连✨✨

🍨效果图

🍹核心代码实现

Element Plus: Tree Tree 树形控件

Element Plus: TreeSelect TreeSelect 树形选择

含有下拉菜单的树形选择器,结合了 el-tree 和 el-selectt 两个组件的功能。

<el-tree-select v-model="formData.parentId" :check-strictly="true" :data="categoryTreeData"
        :render-after-expand="false" :default-expand-all="true" />
  • data 展示数据
  • render-after-expand 属性是默认开启的,所选择的标签名可能不会及时更新显示,您可以把该属性设置为 false 来显示正确的名称
  • 当属性 check-strictly=true 时,任何节点都可以被选择,否则只有子节点可被选择
  • default-expand-all 是否默认展开所有节点

data的数据结构

const data = [
  {
    value: '1',
    label: 'Level one 1',
    children: [
      {
        value: '1-1',
        label: 'Level two 1-1',
        children: [
          {
            value: '1-1-1',
            label: 'Level three 1-1-1',
          },
        ],
      },
    ],
  },
  {
    value: '2',
    label: 'Level one 2',
    children: [
      {
        value: '2-1',
        label: 'Level two 2-1',
        children: [
          {
            value: '2-1-1',
            label: 'Level three 2-1-1',
          },
        ],
      },
      {
        value: '2-2',
        label: 'Level two 2-2',
        children: [
          {
            value: '2-2-1',
            label: 'Level three 2-2-1',
          },
        ],
      },
    ],
  },
]

这是一种父子关系的数据结构,所以在创建数据库时需要对应的关系结构如下

上面的value映射id,label映射name,children代表子类

后端接口

            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>5.8.5</version>
            </dependency>

hutool工具: 树结构工具 中有个自定义字段名的方法

使用如下

@GetMapping("/tree")
    public  List<Tree<Integer>> select(){
        //这里用的MyBatis Plus
        List<CategoryDto> dtos = categoryService.select(new CategoryQueryDto());
        //配置
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        // 自定义属性名 都要默认值的
        treeNodeConfig.setWeightKey("seq");
        treeNodeConfig.setIdKey("id");
        // 最大递归深度
        treeNodeConfig.setDeep(2);
        //转换器
        List<Tree<Integer>> treeNodes = TreeUtil.build(dtos, 0, treeNodeConfig,
                (treeNode, tree) -> {
                    tree.setId(treeNode.getId());
                    tree.setParentId(treeNode.getParentId());
                    tree.setWeight(treeNode.getSeq());
                    tree.setName(treeNode.getName());
                    // 扩展属性 ...
                    tree.putExtra("value", treeNode.getId());
                    tree.putExtra("label", treeNode.getName());
                });
        return treeNodes;
    }

返回treeNodes格式如下

上面的id,seq,parentId,name,这些数据根据需求去考虑是否获取

关键的是扩展属性value,label这两必须要有,目的是与前端树data结构中的value,label照应

// 扩展属性 ...
tree.putExtra("value", treeNode.getId());
tree.putExtra("label", treeNode.getName());

前端调用接口给:data="categoryTreeData"赋值

const categoryTreeData = ref([{ value: 0, label: "全部一级类目" }])
const callCategoryTreeApi = () => {
  categoryApi.tree.call().then((res:any) => {
    // concat 合并数组
    categoryTreeData.value = categoryTreeData.value.concat(res)
  })
}

补充: v-model="formData.parentId"双向绑定父类ID(parentId),主要作用就是赋值和获取值

;