|
|
@@ -20,6 +20,14 @@ const props = withDefaults(
|
|
|
multiple?: boolean
|
|
|
clearable?: boolean
|
|
|
searchable?: boolean
|
|
|
+ sortValueBy?: "INDEX" | "LEVEL" | "ORDER_SELECTED"
|
|
|
+ flat?: boolean
|
|
|
+ // 非平面多选模式(flat=false,multiple=true)时
|
|
|
+ // "ALL"- 任何被选中的节点都将包含在数组中value
|
|
|
+ // "BRANCH_PRIORITY"(默认值) - 如果选中分支节点,则数组中将排除其所有后代value
|
|
|
+ // "LEAF_PRIORITY"- 如果选中分支节点,则该节点本身及其分支后代将从数组中排除,但其叶子代将被包括在内value
|
|
|
+ // "ALL_WITH_INDETERMINATE"- 任何被选中的节点都将包含在数组中,加上不确定的节点value (默认值)
|
|
|
+ valueConsistsOf?: "ALL" | "BRANCH_PRIORITY" | "LEAF_PRIORITY" | "ALL_WITH_INDETERMINATE"
|
|
|
expandedKeys?: Array<string>
|
|
|
defaultExpandLevel?: number
|
|
|
placeholder?: string
|
|
|
@@ -34,9 +42,12 @@ const props = withDefaults(
|
|
|
}>(),
|
|
|
{
|
|
|
multiple: false,
|
|
|
+ flat: false,
|
|
|
clearable: false,
|
|
|
searchable: false,
|
|
|
method: "get",
|
|
|
+ sortValueBy: "LEVEL",
|
|
|
+ valueConsistsOf: "ALL_WITH_INDETERMINATE",
|
|
|
staticOptions: () => {
|
|
|
return [] as Array<TreeOption>
|
|
|
},
|
|
|
@@ -53,8 +64,9 @@ const props = withDefaults(
|
|
|
}
|
|
|
)
|
|
|
const emits = defineEmits<{
|
|
|
- (e: "update:value", v: string): void
|
|
|
+ (e: "update:value", v: string | number | Array<string | number> | null | undefined): void
|
|
|
(e: "select", v: any): void
|
|
|
+ (e: "deselect", v: any): void
|
|
|
}>()
|
|
|
const { staticOptions, url, value, id } = toRefs(props)
|
|
|
const options = ref<Array<TreeOption>>(Object.assign([], staticOptions.value ?? []))
|
|
|
@@ -76,7 +88,9 @@ function formatData(data: any) {
|
|
|
children?.forEach((v: any) => {
|
|
|
childrenItem.push(formatData(v))
|
|
|
})
|
|
|
- item.children = childrenItem
|
|
|
+ if (childrenItem.length) {
|
|
|
+ item.children = childrenItem
|
|
|
+ }
|
|
|
}
|
|
|
return item
|
|
|
}
|
|
|
@@ -90,8 +104,9 @@ function init() {
|
|
|
const item = formatData(v)
|
|
|
options.value.push(item)
|
|
|
})
|
|
|
+
|
|
|
if (!value.value) {
|
|
|
- const val = options.value[0].id
|
|
|
+ const val = props.multiple ? [options.value[0].id] : options.value[0].id
|
|
|
emits("update:value", val)
|
|
|
}
|
|
|
}
|
|
|
@@ -108,9 +123,59 @@ function init() {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+const combineIdChildren = (item: any) => {
|
|
|
+ const items = []
|
|
|
+ items.push(item.id)
|
|
|
+ if (item.children && item.children.length) {
|
|
|
+ item.children.forEach((v: any) => {
|
|
|
+ items.push(...combineIdChildren(v))
|
|
|
+ })
|
|
|
+ }
|
|
|
+ return items
|
|
|
+}
|
|
|
+const findItemIds = (id: string | number, data?: Array<any>): Array<any> => {
|
|
|
+ data = data || options.value
|
|
|
+ const items = []
|
|
|
+ if (data.length) {
|
|
|
+ for (let i = 0; i < data.length; i++) {
|
|
|
+ const item = data[i]
|
|
|
+ if (item["id"] == id) {
|
|
|
+ items.push(...combineIdChildren(item))
|
|
|
+ } else if (item.children && item.children.length) {
|
|
|
+ items.push(...findItemIds(id, item.children))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return items
|
|
|
+}
|
|
|
function onSelect(data: any) {
|
|
|
- //console.log("data", data, data.id)
|
|
|
- emits("update:value", data.id)
|
|
|
+ //console.log("data", data, data.id, findItemIds(data.id))
|
|
|
+ // if (props.multiple) {
|
|
|
+ // if (props.flat) {
|
|
|
+ // const val = Object.assign([], value.value as Array<string | number>)
|
|
|
+ // const needAdd = findItemIds(data.id)
|
|
|
+ // val.push(...needAdd)
|
|
|
+ // emits("update:value", val)
|
|
|
+ // }
|
|
|
+ // } else {
|
|
|
+ // emits("update:value", data.id)
|
|
|
+ // }
|
|
|
+ emits("deselect", data)
|
|
|
+}
|
|
|
+function onDeselect(data: any) {
|
|
|
+ // console.log("data", data, data.id, findItemIds(data.id))
|
|
|
+ // if (props.multiple) {
|
|
|
+ // if (props.flat) {
|
|
|
+ // const needRemove = findItemIds(data.id)
|
|
|
+ // let val = Object.assign([], value.value as Array<string | number>)
|
|
|
+ // val = val.filter((v: any) => {
|
|
|
+ // return needRemove.indexOf(v) < 0
|
|
|
+ // })
|
|
|
+ // emits("update:value", val)
|
|
|
+ // }
|
|
|
+ // } else {
|
|
|
+ // emits("update:value", undefined)
|
|
|
+ // }
|
|
|
emits("select", data)
|
|
|
}
|
|
|
watch(() => props.id, init)
|
|
|
@@ -134,7 +199,11 @@ defineExpose({ load })
|
|
|
:searchable="searchable"
|
|
|
:name="name"
|
|
|
:default-expand-level="defaultExpandLevel"
|
|
|
+ :flat="flat"
|
|
|
+ :sort-value-by="sortValueBy"
|
|
|
+ :value-consists-of="valueConsistsOf"
|
|
|
v-bind="$attrs"
|
|
|
@select="onSelect"
|
|
|
+ @deselect="onDeselect"
|
|
|
/>
|
|
|
</template>
|