cl-tree 添加 modelValue、multiple 参数
This commit is contained in:
@@ -3,11 +3,13 @@
|
|||||||
<view class="p-3">
|
<view class="p-3">
|
||||||
<demo-item :label="t('树形结构')">
|
<demo-item :label="t('树形结构')">
|
||||||
<cl-tree
|
<cl-tree
|
||||||
|
v-model="checkedKeys"
|
||||||
ref="treeRef"
|
ref="treeRef"
|
||||||
:list="list"
|
:list="list"
|
||||||
:icon="isCustomIcon ? 'add-circle-line' : 'arrow-right-s-fill'"
|
:icon="isCustomIcon ? 'add-circle-line' : 'arrow-right-s-fill'"
|
||||||
:expand-icon="isCustomIcon ? 'indeterminate-circle-line' : 'arrow-down-s-fill'"
|
:expand-icon="isCustomIcon ? 'indeterminate-circle-line' : 'arrow-down-s-fill'"
|
||||||
:show-checkbox="true"
|
:checkable="true"
|
||||||
|
:multiple="true"
|
||||||
:check-strictly="checkStrictly"
|
:check-strictly="checkStrictly"
|
||||||
></cl-tree>
|
></cl-tree>
|
||||||
|
|
||||||
@@ -22,6 +24,10 @@
|
|||||||
</cl-list>
|
</cl-list>
|
||||||
</demo-item>
|
</demo-item>
|
||||||
|
|
||||||
|
<demo-item :label="t('选中值')">
|
||||||
|
<cl-text>{{ checkedKeys.join("、") }}</cl-text>
|
||||||
|
</demo-item>
|
||||||
|
|
||||||
<demo-item :label="t('选中操作')">
|
<demo-item :label="t('选中操作')">
|
||||||
<view class="mb-2">
|
<view class="mb-2">
|
||||||
<cl-button @tap="setChecked">{{ t("选中部分节点") }}</cl-button>
|
<cl-button @tap="setChecked">{{ t("选中部分节点") }}</cl-button>
|
||||||
@@ -29,14 +35,6 @@
|
|||||||
|
|
||||||
<view class="mb-2">
|
<view class="mb-2">
|
||||||
<cl-button @tap="getChecked">{{ t("获取选中节点") }}</cl-button>
|
<cl-button @tap="getChecked">{{ t("获取选中节点") }}</cl-button>
|
||||||
|
|
||||||
<cl-text
|
|
||||||
v-if="checkedKeys.length > 0"
|
|
||||||
:pt="{
|
|
||||||
className: '!text-sm p-2'
|
|
||||||
}"
|
|
||||||
>{{ checkedKeys.join(", ") }}</cl-text
|
|
||||||
>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="mb-2">
|
<view class="mb-2">
|
||||||
@@ -47,7 +45,7 @@
|
|||||||
:pt="{
|
:pt="{
|
||||||
className: '!text-sm p-2'
|
className: '!text-sm p-2'
|
||||||
}"
|
}"
|
||||||
>{{ halfCheckedKeys.join(", ") }}</cl-text
|
>{{ halfCheckedKeys.join("、") }}</cl-text
|
||||||
>
|
>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -69,7 +67,7 @@
|
|||||||
:pt="{
|
:pt="{
|
||||||
className: '!text-sm p-2'
|
className: '!text-sm p-2'
|
||||||
}"
|
}"
|
||||||
>{{ expandedKeys.join(", ") }}</cl-text
|
>{{ expandedKeys.join("、") }}</cl-text
|
||||||
>
|
>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -89,9 +87,17 @@
|
|||||||
import DemoItem from "../components/item.uvue";
|
import DemoItem from "../components/item.uvue";
|
||||||
import { t } from "@/locale";
|
import { t } from "@/locale";
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { useTree } from "@/uni_modules/cool-ui";
|
import { useTree, useUi, type ClTreeItem } from "@/uni_modules/cool-ui";
|
||||||
|
|
||||||
const list = useTree([
|
const ui = useUi();
|
||||||
|
|
||||||
|
const list = ref<ClTreeItem[]>([]);
|
||||||
|
|
||||||
|
function refresh() {
|
||||||
|
ui.showLoading();
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
list.value = useTree([
|
||||||
{
|
{
|
||||||
id: "1",
|
id: "1",
|
||||||
label: "华为",
|
label: "华为",
|
||||||
@@ -110,6 +116,7 @@ const list = useTree([
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "1-1-1-2",
|
id: "1-1-1-2",
|
||||||
|
disabled: true,
|
||||||
label: "Mate 40"
|
label: "Mate 40"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -124,6 +131,7 @@ const list = useTree([
|
|||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: "1-1-2-1",
|
id: "1-1-2-1",
|
||||||
|
disabled: true,
|
||||||
label: "P60"
|
label: "P60"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -181,6 +189,7 @@ const list = useTree([
|
|||||||
{
|
{
|
||||||
id: "2",
|
id: "2",
|
||||||
label: "小米",
|
label: "小米",
|
||||||
|
isExpand: true,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: "2-1",
|
id: "2-1",
|
||||||
@@ -314,7 +323,11 @@ const list = useTree([
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
ui.hideLoading();
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
|
||||||
// 是否严格的遵循父子不互相关联
|
// 是否严格的遵循父子不互相关联
|
||||||
const checkStrictly = ref(false);
|
const checkStrictly = ref(false);
|
||||||
@@ -326,7 +339,8 @@ const isCustomIcon = ref(false);
|
|||||||
const treeRef = ref<ClTreeComponentPublicInstance | null>(null);
|
const treeRef = ref<ClTreeComponentPublicInstance | null>(null);
|
||||||
|
|
||||||
// 选中节点的keys
|
// 选中节点的keys
|
||||||
const checkedKeys = ref<(string | number)[]>([]);
|
const checkedKeys = ref<(string | number)[]>(["1-1-1-1", "2-1-1", "2-1-2"]);
|
||||||
|
const checkedKeys2 = ref<string | null>("1-1-1");
|
||||||
|
|
||||||
// 半选节点的keys
|
// 半选节点的keys
|
||||||
const halfCheckedKeys = ref<(string | number)[]>([]);
|
const halfCheckedKeys = ref<(string | number)[]>([]);
|
||||||
@@ -354,7 +368,7 @@ function getHalfChecked() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function expand() {
|
function expand() {
|
||||||
treeRef.value!.setExpandedKeys(["1", "1-1", "2"]);
|
treeRef.value!.setExpandedKeys(["4", "5"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getExpanded() {
|
function getExpanded() {
|
||||||
@@ -370,4 +384,8 @@ function collapseAll() {
|
|||||||
treeRef.value!.collapseAll();
|
treeRef.value!.collapseAll();
|
||||||
expandedKeys.value = [];
|
expandedKeys.value = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onReady(() => {
|
||||||
|
refresh();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,14 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="cl-tree-item__wrapper" :class="[`cl-tree-item--level-${level}`, pt.className]">
|
<view class="cl-tree-item-wrapper" :class="[pt.itemWrapper?.className]">
|
||||||
<view
|
<view
|
||||||
class="cl-tree-item"
|
class="cl-tree-item"
|
||||||
:class="[
|
:class="[
|
||||||
{
|
{
|
||||||
'is-expand': hover,
|
'is-expand': hover,
|
||||||
'is-dark': isDark
|
'is-dark': isDark,
|
||||||
|
'is-checked': item.isChecked == true && ClTree?.checkable == true,
|
||||||
|
'is-half-checked': item.isHalfChecked,
|
||||||
|
'is-disabled': item.disabled,
|
||||||
|
'is-multiple': ClTree?.multiple
|
||||||
},
|
},
|
||||||
pt.className
|
pt.item?.className,
|
||||||
|
item.isChecked == true ? pt.itemChecked?.className : ''
|
||||||
]"
|
]"
|
||||||
|
:style="{
|
||||||
|
paddingLeft: `${level * 50 + 16}rpx`
|
||||||
|
}"
|
||||||
@touchstart="onTouchStart"
|
@touchstart="onTouchStart"
|
||||||
@touchend="onTouchEnd"
|
@touchend="onTouchEnd"
|
||||||
@touchcancel="onTouchEnd"
|
@touchcancel="onTouchEnd"
|
||||||
@@ -16,7 +24,7 @@
|
|||||||
<view class="cl-tree-item__expand" :class="[pt.expand?.className]">
|
<view class="cl-tree-item__expand" :class="[pt.expand?.className]">
|
||||||
<cl-icon
|
<cl-icon
|
||||||
:name="icon"
|
:name="icon"
|
||||||
:size="pt.expandIcon?.size ?? 36"
|
:size="pt.expandIcon?.size ?? 34"
|
||||||
:color="pt.expandIcon?.color"
|
:color="pt.expandIcon?.color"
|
||||||
:pt="{
|
:pt="{
|
||||||
className: pt.expandIcon?.className
|
className: pt.expandIcon?.className
|
||||||
@@ -32,7 +40,7 @@
|
|||||||
>{{ item.label }}</cl-text
|
>{{ item.label }}</cl-text
|
||||||
>
|
>
|
||||||
|
|
||||||
<template v-if="ClTree?.showCheckbox">
|
<template v-if="showCheckbox">
|
||||||
<view
|
<view
|
||||||
class="cl-tree-item__checkbox"
|
class="cl-tree-item__checkbox"
|
||||||
:class="[pt.checkbox?.className]"
|
:class="[pt.checkbox?.className]"
|
||||||
@@ -99,8 +107,9 @@ const props = defineProps({
|
|||||||
|
|
||||||
// 透传属性类型定义,支持自定义各部分样式和图标
|
// 透传属性类型定义,支持自定义各部分样式和图标
|
||||||
type PassThrough = {
|
type PassThrough = {
|
||||||
className?: string; // 外层自定义类名
|
item?: PassThroughProps; // 自定义类名
|
||||||
wrapper?: PassThroughProps; // 外层包裹属性
|
itemChecked?: PassThroughProps; // 选中状态属性
|
||||||
|
itemWrapper?: PassThroughProps; // 外层包裹属性
|
||||||
expand?: PassThroughProps; // 展开区域属性
|
expand?: PassThroughProps; // 展开区域属性
|
||||||
expandIcon?: ClIconProps; // 展开图标属性
|
expandIcon?: ClIconProps; // 展开图标属性
|
||||||
checkbox?: PassThroughProps; // 复选框区域属性
|
checkbox?: PassThroughProps; // 复选框区域属性
|
||||||
@@ -119,6 +128,11 @@ const ClTree = useParent<ClTreeComponentPublicInstance>("cl-tree");
|
|||||||
// 判断当前节点是否有子节点
|
// 判断当前节点是否有子节点
|
||||||
const hasChildren = computed(() => props.item.children != null && props.item.children.length > 0);
|
const hasChildren = computed(() => props.item.children != null && props.item.children.length > 0);
|
||||||
|
|
||||||
|
// 判断当前节点是否显示复选框
|
||||||
|
const showCheckbox = computed(() => {
|
||||||
|
return ClTree?.checkable == true && ClTree?.multiple == true;
|
||||||
|
});
|
||||||
|
|
||||||
// 计算当前节点应显示的图标(展开/收起)
|
// 计算当前节点应显示的图标(展开/收起)
|
||||||
const icon = computed(() => {
|
const icon = computed(() => {
|
||||||
if (ClTree == null) {
|
if (ClTree == null) {
|
||||||
@@ -134,6 +148,10 @@ function toExpand() {
|
|||||||
|
|
||||||
// 切换当前节点的选中状态
|
// 切换当前节点的选中状态
|
||||||
function toChecked() {
|
function toChecked() {
|
||||||
|
if (props.item.disabled == true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ClTree!.setChecked(props.item.id, !(props.item.isChecked ?? false));
|
ClTree!.setChecked(props.item.id, !(props.item.isChecked ?? false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,6 +162,10 @@ const hover = ref(false);
|
|||||||
function onTouchStart() {
|
function onTouchStart() {
|
||||||
hover.value = true;
|
hover.value = true;
|
||||||
toExpand();
|
toExpand();
|
||||||
|
|
||||||
|
if (ClTree?.checkable == true && ClTree?.multiple != true && props.item.disabled != true) {
|
||||||
|
toChecked();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 触摸结束时触发,取消hover
|
// 触摸结束时触发,取消hover
|
||||||
@@ -153,12 +175,9 @@ function onTouchEnd() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.cl-tree-item__wrapper {
|
|
||||||
@apply pl-8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cl-tree-item {
|
.cl-tree-item {
|
||||||
@apply flex flex-row items-center w-full p-2 rounded-lg;
|
@apply flex flex-row items-center w-full rounded-lg;
|
||||||
|
padding: 16rpx;
|
||||||
|
|
||||||
&__expand {
|
&__expand {
|
||||||
@apply w-6 flex items-center justify-center;
|
@apply w-6 flex items-center justify-center;
|
||||||
@@ -172,8 +191,20 @@ function onTouchEnd() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&--level-0 {
|
&.is-disabled {
|
||||||
@apply pl-0;
|
@apply opacity-50;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-checked {
|
||||||
|
@apply bg-primary-100;
|
||||||
|
|
||||||
|
&.is-multiple {
|
||||||
|
@apply bg-transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-dark {
|
||||||
|
@apply bg-primary-500;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="cl-tree">
|
<view class="cl-tree" :class="[pt.className]">
|
||||||
<cl-tree-item
|
<cl-tree-item
|
||||||
v-for="item in data"
|
v-for="item in data"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:item="item"
|
:item="item"
|
||||||
:level="0"
|
:level="0"
|
||||||
:pt="pt"
|
:pt="props.pt"
|
||||||
></cl-tree-item>
|
></cl-tree-item>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, watch, ref, type PropType } from "vue";
|
import { computed, watch, ref, type PropType } from "vue";
|
||||||
import type { ClTreeItem, ClTreeNodeInfo } from "../../types";
|
import type { ClTreeItem, ClTreeNodeInfo } from "../../types";
|
||||||
|
import { first, isEmpty, isEqual, parsePt } from "@/cool";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "cl-tree"
|
name: "cl-tree"
|
||||||
@@ -23,6 +24,11 @@ const props = defineProps({
|
|||||||
type: Object as PropType<any>,
|
type: Object as PropType<any>,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
},
|
},
|
||||||
|
// 绑定值
|
||||||
|
modelValue: {
|
||||||
|
type: [Array, String, Number] as PropType<any | null>,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
// 树形结构数据
|
// 树形结构数据
|
||||||
list: {
|
list: {
|
||||||
type: Array as PropType<ClTreeItem[]>,
|
type: Array as PropType<ClTreeItem[]>,
|
||||||
@@ -38,18 +44,33 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
default: "arrow-down-s-fill"
|
default: "arrow-down-s-fill"
|
||||||
},
|
},
|
||||||
// 是否显示复选框
|
|
||||||
showCheckbox: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
// 是否严格的遵循父子不互相关联
|
// 是否严格的遵循父子不互相关联
|
||||||
checkStrictly: {
|
checkStrictly: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
// 是否可以选择节点
|
||||||
|
checkable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 是否允许多选
|
||||||
|
multiple: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(["update:modelValue", "change"]);
|
||||||
|
|
||||||
|
// 定义透传类型
|
||||||
|
type PassThrough = {
|
||||||
|
className?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 计算样式穿透对象
|
||||||
|
const pt = computed(() => parsePt<PassThrough>(props.pt));
|
||||||
|
|
||||||
// 树数据
|
// 树数据
|
||||||
const data = ref<ClTreeItem[]>(props.list);
|
const data = ref<ClTreeItem[]>(props.list);
|
||||||
|
|
||||||
@@ -266,9 +287,16 @@ function setChecked(key: string | number, flag: boolean): void {
|
|||||||
const nodeInfo = findNodeInfo(key); // 查找节点信息
|
const nodeInfo = findNodeInfo(key); // 查找节点信息
|
||||||
if (nodeInfo == null) return; // 节点不存在则返回
|
if (nodeInfo == null) return; // 节点不存在则返回
|
||||||
|
|
||||||
|
// 非多选模式下,清空所有选中状态
|
||||||
|
if (!props.multiple) {
|
||||||
|
clearChecked();
|
||||||
|
}
|
||||||
|
|
||||||
// 设置当前节点选中状态
|
// 设置当前节点选中状态
|
||||||
nodeInfo.node.isChecked = flag;
|
nodeInfo.node.isChecked = flag;
|
||||||
|
|
||||||
|
// 多选模式下处理
|
||||||
|
if (props.multiple) {
|
||||||
// 非严格模式下处理父子联动
|
// 非严格模式下处理父子联动
|
||||||
if (!props.checkStrictly) {
|
if (!props.checkStrictly) {
|
||||||
// 设置所有子孙节点的选中状态
|
// 设置所有子孙节点的选中状态
|
||||||
@@ -280,6 +308,7 @@ function setChecked(key: string | number, flag: boolean): void {
|
|||||||
// 更新所有祖先节点的状态
|
// 更新所有祖先节点的状态
|
||||||
updateAncestorsCheckState(key);
|
updateAncestorsCheckState(key);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -386,11 +415,6 @@ function setExpanded(key: string | number, flag: boolean): void {
|
|||||||
* @param keys 需要展开的节点id数组
|
* @param keys 需要展开的节点id数组
|
||||||
*/
|
*/
|
||||||
function setExpandedKeys(keys: (string | number)[]): void {
|
function setExpandedKeys(keys: (string | number)[]): void {
|
||||||
// 先重置所有节点为收起状态
|
|
||||||
nodeMap.value.forEach((info: ClTreeNodeInfo) => {
|
|
||||||
info.node.isExpand = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 设置指定节点为展开状态
|
// 设置指定节点为展开状态
|
||||||
for (let i = 0; i < keys.length; i++) {
|
for (let i = 0; i < keys.length; i++) {
|
||||||
const nodeInfo = findNodeInfo(keys[i]);
|
const nodeInfo = findNodeInfo(keys[i]);
|
||||||
@@ -445,29 +469,96 @@ function expandAll(): void {
|
|||||||
/**
|
/**
|
||||||
* 收起所有节点
|
* 收起所有节点
|
||||||
*/
|
*/
|
||||||
function collapseAll(): void {
|
function collapseAll() {
|
||||||
// 遍历所有节点,将isExpand设为false
|
// 遍历所有节点,将isExpand设为false
|
||||||
nodeMap.value.forEach((info: ClTreeNodeInfo) => {
|
nodeMap.value.forEach((info: ClTreeNodeInfo) => {
|
||||||
info.node.isExpand = false;
|
info.node.isExpand = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步绑定值
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* 同步绑定值到外部
|
||||||
|
* 当内部选中状态变化时,更新外部的modelValue,并触发change事件
|
||||||
|
*/
|
||||||
|
function syncModelValue() {
|
||||||
|
// 如果树数据为空,则不更新绑定值
|
||||||
|
if (isEmpty(data.value)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前所有选中的key
|
||||||
|
const checkedKeys = getCheckedKeys();
|
||||||
|
|
||||||
|
// 如果外部modelValue为null,或当前选中key与外部modelValue不一致,则更新
|
||||||
|
if (props.modelValue == null || !isEqual(checkedKeys, props.modelValue!)) {
|
||||||
|
// 如果多选,直接传递数组;否则只传第一个选中的key
|
||||||
|
const value = props.multiple ? checkedKeys : first(checkedKeys);
|
||||||
|
|
||||||
|
emit("update:modelValue", value); // 通知外部更新modelValue
|
||||||
|
emit("change", value); // 触发change事件
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步外部modelValue到内部选中状态
|
||||||
|
* 当外部modelValue变化时,更新内部选中状态,并保持与外部一致
|
||||||
|
*/
|
||||||
|
function syncCheckedState() {
|
||||||
|
// 如果外部modelValue为null,则不处理
|
||||||
|
if (props.modelValue == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前所有选中的key
|
||||||
|
const checkedKeys = getCheckedKeys();
|
||||||
|
|
||||||
|
// 如果当前选中key与外部modelValue不一致,则进行同步
|
||||||
|
if (!isEqual(checkedKeys, props.modelValue!)) {
|
||||||
|
if (Array.isArray(props.modelValue)) {
|
||||||
|
setCheckedKeys(props.modelValue!); // 多选时,设置所有选中key
|
||||||
|
} else {
|
||||||
|
setChecked(props.modelValue!, true); // 单选时,设置单个选中key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
syncModelValue(); // 同步绑定值到外部
|
||||||
|
}
|
||||||
|
|
||||||
// 监听props.list变化,同步到内部数据
|
// 监听props.list变化,同步到内部数据
|
||||||
watch(
|
watch(
|
||||||
computed(() => props.list),
|
computed(() => props.list),
|
||||||
(val: ClTreeItem[]) => {
|
(val: ClTreeItem[]) => {
|
||||||
data.value = val;
|
data.value = val;
|
||||||
|
|
||||||
|
// 检查选中状态
|
||||||
|
syncCheckedState();
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
// 监听modelValue变化
|
||||||
|
watch(
|
||||||
|
computed(() => [props.modelValue ?? 0]),
|
||||||
|
() => {
|
||||||
|
syncCheckedState();
|
||||||
},
|
},
|
||||||
{ immediate: true, deep: true }
|
{ immediate: true, deep: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
// 监听树数据变化,自动更新选中状态
|
// 监听树数据变化
|
||||||
watch(
|
watch(
|
||||||
data,
|
data,
|
||||||
() => {
|
() => {
|
||||||
if (!props.checkStrictly) {
|
// 自动更新选中状态
|
||||||
|
if (!props.checkStrictly && props.multiple) {
|
||||||
updateAllCheckStates();
|
updateAllCheckStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 更新绑定值
|
||||||
|
syncModelValue();
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
);
|
);
|
||||||
@@ -475,8 +566,9 @@ watch(
|
|||||||
defineExpose({
|
defineExpose({
|
||||||
icon: computed(() => props.icon),
|
icon: computed(() => props.icon),
|
||||||
expandIcon: computed(() => props.expandIcon),
|
expandIcon: computed(() => props.expandIcon),
|
||||||
showCheckbox: computed(() => props.showCheckbox),
|
|
||||||
checkStrictly: computed(() => props.checkStrictly),
|
checkStrictly: computed(() => props.checkStrictly),
|
||||||
|
checkable: computed(() => props.checkable),
|
||||||
|
multiple: computed(() => props.multiple),
|
||||||
clearChecked,
|
clearChecked,
|
||||||
setChecked,
|
setChecked,
|
||||||
setCheckedKeys,
|
setCheckedKeys,
|
||||||
|
|||||||
4
uni_modules/cool-ui/types/component.d.ts
vendored
4
uni_modules/cool-ui/types/component.d.ts
vendored
@@ -210,9 +210,9 @@ declare type ClSlideVerifyComponentPublicInstance = {
|
|||||||
declare type ClTreeComponentPublicInstance = {
|
declare type ClTreeComponentPublicInstance = {
|
||||||
icon: string;
|
icon: string;
|
||||||
expandIcon: string;
|
expandIcon: string;
|
||||||
showCheckbox: boolean;
|
checkable: boolean;
|
||||||
|
multiple: boolean;
|
||||||
checkStrictly: boolean;
|
checkStrictly: boolean;
|
||||||
accordion: boolean;
|
|
||||||
clearChecked: () => void;
|
clearChecked: () => void;
|
||||||
setChecked: (key: string | number, flag: boolean) => void;
|
setChecked: (key: string | number, flag: boolean) => void;
|
||||||
setCheckedKeys: (keys: (string | number)[]) => void;
|
setCheckedKeys: (keys: (string | number)[]) => void;
|
||||||
|
|||||||
Reference in New Issue
Block a user