相关知识点链接
Tree 的勾选传导:ant-design.antgroup.com/docs/blog/c…
注:这个主要是说明为什么在disabled状态下不会传导没有回显的问题
Tree树形控件: next.antdv.com/components/…
解决方法
解决结果
以下只是部分代码
使用的自定义图标去解决的,根据后端返回的选中的字符串数组formData.menuTitleList,以及返回的mobile_treeData的树形控件数据
<template>
<a-tree
v-if="defaultExpandedKeys.length > 0"
v-model:checkedKeys="formData.menuTitleList"
:tree-data="mobile_treeData"
:show-icon="data && data.isStatic"
:default-expanded-keys="defaultExpandedKeys"
>
<!--使用默认图标 给图标添加类名 -->
<template #icon="{ dataRef, title, key }">
<!--选中的 -->
<span
class="right"
v-if="formData.menuTitleList.includes(key)"
:disabled="true"
></span>
<!--半回显:自身没有被选中,子元素有被选中的 -->
<span
v-if="!formData.menuTitleList.includes(key) && dataRef.indeterminate"
:class="dataRef.indeterminate ? 'indeterminate' : ''"
>
</span>
<!--没有选中的子元素也没有选中的 -->
<span
class="ranger"
v-if="!formData.menuTitleList.includes(key) && !dataRef.indeterminate"
:disabled="true"
></span>
</template>
<template #title="{ title, key }">
<span v-if="key === '0-0-1-0'" style="color: #1890ff">{{ title }}</span>
<span v-else>{{ title }}</span>
</template>
</a-tree>
</template>
<script setup>
import {ref,unref} from 'vue'
const formData = ref({
menuTitleList:[]
})
const mobile_treeData = ref([])
//给获取的treeData数据设置是否禁用以及解决禁用父节点无法半回显问题
function disabled_treeData(
list: any[],
disabled: boolean = false,
_obj: any,
_arr: any[],
) {
list?.forEach((val) => {
val.disableCheckbox = disabled;
if (val.children && val.children.length) {
disabled_treeData(val.children, disabled, val, _arr);
//这里是为了回显到最外层的父节点,只要有子节点是半回显状态,父节点也应该是半回显状态
if (val.indeterminate) {
_obj.indeterminate = true;
}
} else {
// 如果_arr数组中存在等于val.key的值,则给父节点设置半选中状态
if (_arr.includes(val.key)) {
_obj.indeterminate = true;
}
}
});
return list;
}
//如果获取到的树形控件数据不会重新获取,,调用这个方法把之前设置了半回显的节点返回最原始的状态
function disabled_treeDatas(list?: any[], disabled: boolean = false) {
list?.forEach((val) => {
val.disableCheckbox = disabled;
val.indeterminate = false;
if (val.children && val.children.length) disabled_treeDatas(val.children, disabled);
});
return list;
}
//调用方法
const getTreeData = () => {
mobile_treeData.value = disabled_treeData(
unref(mobile_treeData),
true,
unref(mobile_treeData),
formData.value.menuTitleList,
*);*
}
</script>
<style lang='less' scoped>
.ant-tree .ant-tree-node-content-wrapper {
display: flex;
align-items: center;
}
.indeterminate,
.right,
.ranger {
position: relative;
top: 0;
left: 0;
display: block;
width: 16px;
height: 16px;
direction: ltr;
background-color: #fff;
border: 1px solid #d9d9d9;
border-radius: 2px;
border-collapse: separate;
transition: all 0.3s;
background-color: #f5f5f5;
border-color: #d9d9d9 !important;
margin-top: 4px;
}
.indeterminate:after {
top: 50%;
left: 50%;
width: 8px;
height: 8px;
background-color: #d9d9d9;
border: 0;
transform: translate(-50%, -50%) scale(1);
opacity: 1;
content: ' ';
position: absolute;
}
.right::after {
position: absolute;
display: table;
border: 2px solid #fff;
border-top: 0;
border-left: 0;
transform: rotate(45deg) scale(1) translate(-50%, -50%);
opacity: 1;
transition: all 0.2s cubic-bezier(0.12, 0.4, 0.29, 1.46) 0.1s;
content: ' ';
border-color: rgba(0, 0, 0, 0.25);
animation-name: none;
top: 50%;
left: 21.5%;
width: 5.71428571px;
height: 9.14285714px;
}
.ranger::after {
content: ' ';
width: 0;
}
</style>
注意:因为项目中配置角色权限时用到,就进入页面调用获取树形控件的数据的接口,点击不同角色时选中的不一样,所以在弹窗关闭时要调用disabled_treeDatas方法,把数据回归到之前的状态,在弹窗开启时在获取此角色选中列表,再调用disabled_treeData方法去进行父节点的半选中回显
项目中需要默认展开到二级节点
<srcipt setup>
function disabled_treeData(
list: any[],
disabled: boolean = false,
_obj: any,
_arr: any[],
index = 0,
expandKey: any[],
) {
list?.forEach((val) => {
val.disableCheckbox = disabled;
if (val.children && val.children.length) {
if (index == 0) {
expandKey.push(val.key); //默认展开数组
val.children.forEach((val) => {
if (val.children && val.children.length) {
expandKey.push(val.key);
}
});
}
disabled_treeData(val.children, disabled, val, _arr, index + 1, expandKey);
if (val.indeterminate) {
_obj.indeterminate = true;
}
} else {
// 如果_arr数组中存在等于val.key的值,则给父节点设置半选中状态
if (_arr.includes(val.key)) {
_obj.indeterminate = true;
}
if (index > 1) {
index -= 1;
}
}
});
return list;
}
</script>
注意:disabled_treeData跟上面的是同一个方法,因为需求增加,修改了一些,在弹窗关闭时要把expandKey设置为空,弹窗开启时调用disabled_treeData,为了防止用户展开其他节点或者关闭其他节点,重新进来不是默认展开状态