Element-plus、Element-ui之Tree 树形控件回显Bug问题。

需求:提交时,需要把选中状态和半选中状态 的数据id提交。如图所示:

数据回显时,会出现代码如下:

javascript 复制代码
<template>
  <el-tree ref="treeRef" :data="data" show-checkbox node-key="id" :props="defaultProps"> </el-tree>
</template>

<script setup>
import { ref, onMounted } from 'vue';

const data = ref([
  {
    id: 1,
    label: '一级 1',
    children: [
      {
        id: 2,
        label: '二级 2',
        children: [
          { id: 3, label: '三级 3' },
          { id: 4, label: '三级 4' },
        ],
      },
    ],
  },
  {
    id: 5,
    label: '一级 5',
    children: [
      { id: 6, label: '二级 6' },
      { id: 7, label: '二级 7' },
    ],
  },
  {
    id: 8,
    label: '一级 8',
    children: [
      { id: 9, label: '二级 9' },
      {
        id: 10,
        label: '二级 10',
        children: [
          { id: 11, label: '三级 11' },
          { id: 12, label: '三级 12' },
        ],
      },
    ],
  },
]);
// 树组件
const treeRef = ref(null);
const defaultProps = ref({ children: 'children', label: 'label' });
// 回显数据
const dataPlayback = ref([1, 2, 4, 5, 6, 7, 8, 10, 12]);

onMounted(() => {
  // 回显数据 赋值
  treeRef.value.setCheckedKeys(dataPlayback.value);
});
</script>

数据回显问题,如图所示:

修复方法如下:

javascript 复制代码
<template>
  <el-tree ref="treeRef" :data="data" show-checkbox node-key="id" :props="defaultProps"> </el-tree>
  <el-button @click="submit">提交</el-button>
  <span> {{ submitData }}</span>
</template>

<script setup>
import { ref, onMounted } from 'vue';

const data = ref([
  {
    id: 1,
    label: '一级 1',
    children: [
      {
        id: 2,
        label: '二级 2',
        children: [
          { id: 3, label: '三级 3' },
          { id: 4, label: '三级 4' },
        ],
      },
    ],
  },
  {
    id: 5,
    label: '一级 5',
    children: [
      { id: 6, label: '二级 6' },
      { id: 7, label: '二级 7' },
    ],
  },
  {
    id: 8,
    label: '一级 8',
    children: [
      { id: 9, label: '二级 9' },
      {
        id: 10,
        label: '二级 10',
        children: [
          { id: 11, label: '三级 11' },
          { id: 12, label: '三级 12' },
        ],
      },
    ],
  },
]);
// 树组件
const treeRef = ref(null);
const defaultProps = ref({ children: 'children', label: 'label' });
// 回显数据
const dataPlayback = ref([1, 2, 4, 5, 6, 7, 8, 10, 12]);
// 提交数据
const submitData = ref([]);

// 提取含有 children 的所有节点id
const getContainChildrenNode = (data) => {
  let ids = [];
  const recurse = (item) => {
    if (Array.isArray(item)) {
      item.forEach((node) => {
        if (node.children && node.children.length) {
          // 含有子项的节点id
          ids.push(node.id);
          recurse(node.children);
        }
      });
    }
  };
  // 调用递归函数
  recurse(data);
  // 返回含有 children 的所有节点id
  return ids;
};

// 提交
const submit = () => {
  submitData.value = [...treeRef.value.getCheckedKeys(), ...treeRef.value.getHalfCheckedKeys()]; //得到 所有选中的节点id [ 4, 5, 6, 7, 12, 1, 2, 8, 10 ]
};

onMounted(() => {
  // 收集所有顶级节点的值
  const nodeIds = getContainChildrenNode(data.value); // 得到 含有 children 的所有节点id [1, 2, 5, 8, 10]

  // 过滤掉 顶级节点的值
  const treeVal = dataPlayback.value.filter((item) => !nodeIds.includes(item)); // 得到 回显数据 [4, 6, 7, 12]

  // 回显数据 赋值
  treeRef.value.setCheckedKeys(treeVal);
});
</script>
相关推荐
程序员黄同学1 小时前
请谈谈 Vue 中的 key 属性的重要性,如何确保列表项的唯一标识?
前端·javascript·vue.js
繁依Fanyi1 小时前
巧妙实现右键菜单功能,提升用户操作体验
开发语言·前端·javascript·vue.js·uni-app·harmonyos
前端御书房1 小时前
前端防重复请求终极方案:从Loading地狱到精准拦截的架构升级
前端·javascript
web182854825121 小时前
nginx 部署前端vue项目
前端·vue.js·nginx
程序员黄同学1 小时前
解释 Vue 中的虚拟 DOM,如何通过 Diff 算法最小化真实 DOM 更新次数?
开发语言·前端·javascript
果粒chenl2 小时前
css+js提问
前端·javascript·css
memorycx2 小时前
Vue02
前端·javascript·vue.js
道不尽世间的沧桑5 小时前
第17篇:网络请求与Axios集成
开发语言·前端·javascript
bin91538 小时前
DeepSeek 助力 Vue 开发:打造丝滑的复制到剪贴板(Copy to Clipboard)
前端·javascript·vue.js·ecmascript·deepseek
晴空万里藏片云9 小时前
elment Table多级表头固定列后,合计行错位显示问题解决
前端·javascript·vue.js