init
This commit is contained in:
17
src/component/treeSelect/index.less
Normal file
17
src/component/treeSelect/index.less
Normal file
@@ -0,0 +1,17 @@
|
||||
.layui-tree-select {
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.layui-tree-select-content {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.layui-tree-select .layui-icon-triangle-d {
|
||||
transition: all 0.3s;
|
||||
-webkit-transition: all 0.3s;
|
||||
color: var(--global-neutral-color-8);
|
||||
}
|
||||
|
||||
.layui-tree-select .layui-icon-triangle-d.triangle {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
5
src/component/treeSelect/index.ts
Normal file
5
src/component/treeSelect/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { withInstall, WithInstallType } from "../../utils";
|
||||
import Component from "./index.vue";
|
||||
|
||||
const component: WithInstallType<typeof Component> = withInstall(Component);
|
||||
export default component;
|
||||
153
src/component/treeSelect/index.vue
Normal file
153
src/component/treeSelect/index.vue
Normal file
@@ -0,0 +1,153 @@
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "LayTreeSelect",
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import "./index.less";
|
||||
import { computed, ref, watch } from "vue";
|
||||
import { getNode } from "../../utils/treeUtil";
|
||||
import { TreeSelectSize } from "./interface";
|
||||
|
||||
export interface TreeSelectProps {
|
||||
data: any;
|
||||
modelValue: any;
|
||||
disabled?: boolean;
|
||||
placeholder?: string;
|
||||
multiple?: boolean;
|
||||
allowClear?: boolean;
|
||||
collapseTagsTooltip?: boolean;
|
||||
minCollapsedNum?: number;
|
||||
size?: TreeSelectSize;
|
||||
checkStrictly?: boolean;
|
||||
}
|
||||
|
||||
export interface TreeSelectEmits {
|
||||
(e: "update:modelValue", value: string): void;
|
||||
(e: "change", value: string): void;
|
||||
(e: "search", value: string): void;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<TreeSelectProps>(), {
|
||||
disabled: false,
|
||||
placeholder: "请选择",
|
||||
multiple: false,
|
||||
allowClear: false,
|
||||
collapseTagsTooltip: true,
|
||||
minCollapsedNum: 3,
|
||||
checkStrictly: true,
|
||||
size: "md",
|
||||
});
|
||||
|
||||
const singleValue = ref();
|
||||
const multipleValue = ref(["1"]);
|
||||
const openState = ref(false);
|
||||
const dropdownRef = ref();
|
||||
const emits = defineEmits<TreeSelectEmits>();
|
||||
|
||||
const selectedValue = computed({
|
||||
get() {
|
||||
return props.modelValue;
|
||||
},
|
||||
set(value) {
|
||||
emits("update:modelValue", value);
|
||||
emits("change", value);
|
||||
},
|
||||
});
|
||||
|
||||
const checkedKeys = computed({
|
||||
get() {
|
||||
return props.multiple ? props.modelValue : [];
|
||||
},
|
||||
set(value) {
|
||||
if (props.multiple) {
|
||||
emits("update:modelValue", value);
|
||||
emits("change", value);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
watch(
|
||||
selectedValue,
|
||||
() => {
|
||||
if (props.multiple) {
|
||||
multipleValue.value = selectedValue.value.map((value: any) => {
|
||||
const node: any = getNode(props.data, value);
|
||||
node.label = node.title;
|
||||
node.closable = !node.disabled;
|
||||
return node;
|
||||
});
|
||||
} else {
|
||||
const node: any = getNode(props.data, selectedValue.value);
|
||||
if (node) {
|
||||
singleValue.value = node.title;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
);
|
||||
|
||||
const handleClick = (node: any) => {
|
||||
dropdownRef.value.hide();
|
||||
selectedValue.value = node.id;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="layui-tree-select" :class="{ 'layui-disabled': disabled }">
|
||||
<lay-dropdown
|
||||
ref="dropdownRef"
|
||||
:disabled="disabled"
|
||||
:update-at-scroll="true"
|
||||
@show="openState = true"
|
||||
@hide="openState = false"
|
||||
>
|
||||
<lay-tag-input
|
||||
:size="size"
|
||||
:allow-clear="allowClear"
|
||||
:placeholder="placeholder"
|
||||
:collapseTagsTooltip="collapseTagsTooltip"
|
||||
:minCollapsedNum="minCollapsedNum"
|
||||
:disabledInput="true"
|
||||
v-model="multipleValue"
|
||||
v-if="multiple"
|
||||
>
|
||||
<template #suffix>
|
||||
<lay-icon
|
||||
type="layui-icon-triangle-d"
|
||||
:class="{ triangle: openState }"
|
||||
></lay-icon>
|
||||
</template>
|
||||
</lay-tag-input>
|
||||
<lay-input
|
||||
v-else
|
||||
v-model="singleValue"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:readonly="true"
|
||||
:size="size"
|
||||
>
|
||||
<template #suffix>
|
||||
<lay-icon
|
||||
type="layui-icon-triangle-d"
|
||||
:class="{ triangle: openState }"
|
||||
></lay-icon>
|
||||
</template>
|
||||
</lay-input>
|
||||
<template #content>
|
||||
<div class="layui-tree-select-content">
|
||||
<lay-tree
|
||||
:data="data"
|
||||
:onlyIconControl="true"
|
||||
:show-checkbox="multiple"
|
||||
:check-strictly="checkStrictly"
|
||||
v-model:selectedKey="selectedValue"
|
||||
v-model:checkedKeys="checkedKeys"
|
||||
@node-click="handleClick"
|
||||
></lay-tree>
|
||||
</div>
|
||||
</template>
|
||||
</lay-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
1
src/component/treeSelect/interface.ts
Normal file
1
src/component/treeSelect/interface.ts
Normal file
@@ -0,0 +1 @@
|
||||
export type TreeSelectSize = "lg" | "md" | "sm" | "xs";
|
||||
Reference in New Issue
Block a user