1. 需求

点击表单出现弹框,弹框中是el-tree选择器
在这里插入图片描述
在这里插入图片描述
el-tree选择器中的每个层级都可选,但仅支持单选,并且可以实时筛选
在这里插入图片描述
选中后的结果以从高到低的层级名称显示,如图:
在这里插入图片描述

2. 需要解决的问题

2.1 数据处理

后端传过来的数据格式与el-tree内置的数据格式不一,需要做数据处理。
el-tree需要的数据格式:

const data: Tree[] = [
  {
    id: 1,
    label: 'Level one 1',
    children: [
      {
        id: 4,
        label: 'Level two 1-1',
        children: [
          {
            id: 9,
            label: 'Level three 1-1-1',
          },
          {
            id: 10,
            label: 'Level three 1-1-2',
          },
        ],
      },
    ],
  },
  {
    id: 2,
    label: 'Level one 2',
    children: [
      {
        id: 5,
        label: 'Level two 2-1',
      },
      {
        id: 6,
        label: 'Level two 2-2',
      },
    ],
  },
]

后端传给我的数据格式:
在这里插入图片描述
所以我要将我圈出来的不同的数组名统一,最终改成如下格式:
在这里插入图片描述

2.2 获取所有父节点ID和Name

选中某个值后,得到的data是这样的:
在这里插入图片描述
结果中只有选中值的ID和Name,但最终显示的结果与传给后端的结果是需要有所有父节点的ID和Name的,需要处理。

3. 解决数据处理问题

template:
在这里插入图片描述

3.1 ref,筛选

在setup()中声明并使用targetTreeRef进行信息筛选,最后别忘记return出去:

const targetTreeRef = ref<InstanceType<typeof ElTree>>();
const targetFilterInfo = ref("");  // 筛选信息

// el-tree控件-筛选
watch(targetFilterInfo, (val) => {
	targetTreeRef.value!.filter(val);
});
const targetFilter = (value: string, data: Tree) => {
	if (!value) return true;
	return data.Name.includes(value);
};

return { targetTreeRef, targetFilterInfo };

3.2 props

const targetProps = {
	children: "Children",
	label: "Name",
};

return { targetProps };

3.3 data处理

定义数据:

interface Tree {
	ID: string;
	Name: string;
	Children?: Tree[];
}
const targetOpts = ref<Tree[]>([
	{
		ID: "",
		Name: "",
		Children: [],
	},
]);

return { targetOpts }

拿到后端数据后进行递归处理:

// 递归修改targetOpts数据格式,实质是将不同的数组名称统一为Children
    const targetsToTree = (obj: any) => {
    // obj是传进来的后端原始数据, 第一层是个对象,后面是数组
      let arr: any[] = [];
      if (obj instanceof Array) {
        obj.forEach((item) => {
          arr.push({
            Name: item.Name,
            ID: item.ID,
            Children: targetsToTree(
              item.Groups || item.Stations || item.Slots || {}
            ),
          });
        });
      } else {
        // 第一层对象 直接push,将第二层数据的名称改为Children
        Object.keys(obj).map((item) => {
          console.log("values", item);
          arr.push({
            Name: obj[item].Name,
            ID: obj[item].ID,
            Children: targetsToTree(obj[item].Zones),
          });
        });
      }
      return arr;
    };

4. 解决获取父节点信息的问题

4.1 声明

const targetInfo = reactive<{
	resultArr: Tree[];
	index: number;
}>({
	resultArr: [], // target选择后的数组
	index: 0, // 当前操作的target的index
});

4.2 @node-click方法

在这里插入图片描述
node-click方法可以接收两个参数,(data, e),第二个参数中有parent的信息,但只有第一级parent的信息,所以需要递归找到所有parent的信息:
在这里插入图片描述

// 处理选中target数据,最终得到由高层到底层的数组
const handleTargetInfo = (data: Tree, e: any) => {
	console.log("data", data, e);
	targetInfo.resultArr = [];
	handleTarget(e);
};
const handleTarget = (node: any) => {
	// 递归得到target结果数组
	if (!node.parent) return;
	targetInfo.resultArr.unshift(node.data);
	handleTarget(node.parent);
};

最后

赋值就不说了,根据需求不同进行赋值。

Logo

前往低代码交流专区

更多推荐