封装antdv的仅适用于级联 TreeSelect 树型选择控件

1 篇文章 0 订阅

封装antdv的仅适用于级联 TreeSelect 树型选择控件

1. 效果

  • 支持多选
    在这里插入图片描述

  • 不支持多选

在这里插入图片描述

2. 组件

<template>
  <a-tree-select
    style="width: 100%"
    :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
    :value="currentValue"
    :multiple="multiple"
    :allow-clear="allowClear"
    :placeholder="placeholder"
    :tree-default-expand-all="treeDefaultExpandAll"
    :treeNodeFilterProp="treeNodeFilterProp"
    :replaceFields="replaceFields"
    :tree-data="treeData"
    :labelInValue="true"
    @change="onChange"
  />
</template>

<script>
export default {
  name: "TreeSelect",
  props: {
    // 选择框默认文字
    placeholder: {
      type: String,
      required: false,
      default: "",
    },
    // 替换 treeNode 中 title,value,key,children 字段为 treeData 中对应的字段
    replaceFields: {
      type: Object,
      required: false,
      default: () => {
        return {
          children: "children",
          title: "title",
          key: "key",
          value: "value",
        };
      },
    },
    // 是否展开所有树节点
    treeDefaultExpandAll: {
      type: Boolean,
      required: false,
      default: false,
    },
    // 输入项过滤对应的 treeNode 属性
    treeNodeFilterProp: {
      type: String,
      required: false,
      default: "value",
    },
    // 是否显示清除按钮
    allowClear: {
      type: Boolean,
      required: false,
      default: true,
    },
    // 是否支持多选(当设置 treeCheckable 时自动变为 true)
    multiple: {
      type: Boolean,
      required: false,
      default: true,
    },
    // 数据
    treeData: {
      type: Array,
      required: true,
    },
  },
  data() {
    return {
      currentValue: undefined,
    };
  },
  methods: {
    // 选中树节点时调用此函数
    onChange(val) {
      let { title } = this.replaceFields;
      this.currentValue = val;
      // 支持多选
      if (val.constructor == Array) {
        val.forEach((item) => {
          item.label = this.getTreePath(
            this.treeData,
            title,
            (v) => v.value === item.value
          );
        });
      } else {
        // val.constructor == Object 的情况   // 不支持多选
        val.label = this.getTreePath(this.treeData, title, (v) => v.value === val.value);
      }
      this.$emit("Change", val);
    },
    /**
     * 获取树形数据的某个元素的所有父节点
     * @param {tree} 属性tree-data的数据
     * @param {title} 根据 title 去查询父级的显示内容
     * @param {func} 自定义查询的参数名,匹配目标节点值
     * @param {path} 存储目标元素的所有父节点的数组
     * @return {*} 涵盖某个元素的所有父节点 ['level1','level2','level3']
     */
    getTreePath(tree, title, func, path = []) {
      if (!tree) return [];
      for (const i of tree) {
        path.push(i[title]); // push 树节点显示的内容
        if (func(i)) return this.formatPath(path);
        if (i.children) {
          const findChildren = this.getTreePath(i.children, title, func, path);
          if (findChildren.length) return findChildren;
        }
        path.pop();
      }
      return [];
    },
    /**
     * 将父子级数组 ['level1','level2','level3'] 转换成级联 level1/level2/level3 格式
     * @param {path} 节点label数组
     * @return {*} label/label/label格式字符串
     */
    formatPath(path) {
      let str = "";
      path.forEach((item) => {
        item = item.trim();
        str = str + item + "/";
      });
      return str.slice(0, str.length - 1);
    },
  },
};
</script>

3. 使用

<template>
  <TreeSelect
    :tree-data="treeData"
    v-model="value"
    placeholder="Please select"
    :replaceFields="replaceFields"
    :multiple='false'     // 重点 - true表示支持多选 false表示支持单选
  />
</template>

<script>
import TreeSelect from "./TreeSelect.vue";
const treeData = [
  {
    label: "Node1",
    value: "0-0",
    key: "0-0",
    children: [
      {
        label: "Child Node1",
        value: "0-0-0",
        key: "0-0-0",
        children: [
          {
            label: "Child Node1-1",
            value: "0-0-0-0",
            key: "0-0-0-0",
          },
        ],
      },
    ],
  },
  {
    label: "Node2",
    value: "0-1",
    key: "0-1",
    children: [
      {
        label: "Child Node3",
        value: "0-1-0",
        key: "0-1-0",
        disabled: true,
      },
      {
        label: "Child Node4",
        value: "0-1-1",
        key: "0-1-1",
      },
      {
        label: "Child Node5",
        value: "0-1-2",
        key: "0-1-2",
      },
    ],
  },
];
export default {
  components: { TreeSelect },
  data() {
    return {
      value: [],
      treeData,
      replaceFields: {
        key: "key",
        value: "value",
        children: "children",
        title: "label",
      },
    };
  }
};
</script>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一个简单的前端手写级件示例,您可以根据自己的需求进行修改和优化。 HTML部分: ```html <div id="tree"></div> ``` JS部分: ```javascript var data = [ { "id": 1, "name": "节点1", "parentId": 0 }, { "id": 2, "name": "节点2", "parentId": 0 }, { "id": 3, "name": "节点1-1", "parentId": 1 }, { "id": 4, "name": "节点1-2", "parentId": 1 }, { "id": 5, "name": "节点2-1", "parentId": 2 }, { "id": 6, "name": "节点2-2", "parentId": 2 }, { "id": 7, "name": "节点1-1-1", "parentId": 3 }, { "id": 8, "name": "节点1-1-2", "parentId": 3 } ]; var tree = document.getElementById("tree"); function createTree(data, parentId, level) { var ul = document.createElement("ul"); for (var i = 0; i < data.length; i++) { if (data[i].parentId == parentId) { var li = document.createElement("li"); li.innerHTML = data[i].name; li.setAttribute("data-id", data[i].id); li.setAttribute("data-level", level); ul.appendChild(li); var childUl = createTree(data, data[i].id, level + 1); if (childUl) { li.appendChild(childUl); } } } return ul.innerHTML ? ul : null; } tree.innerHTML = createTree(data, 0, 1).outerHTML; var selectedId = null; tree.addEventListener("click", function(e) { var target = e.target; if (target.tagName == "LI") { var id = target.getAttribute("data-id"); var level = target.getAttribute("data-level"); if (id != selectedId) { selectedId = id; console.log("您选择了ID为" + id + ",层级为" + level + "的节点"); } } }); ``` 这段代码实现了一个简单的形结构,您可以根据自己的需要进行修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值