(component): 修复 select 无法异步加载的问题

This commit is contained in:
就眠儀式 2022-09-30 17:06:09 +08:00
parent 1819e88ff0
commit 954e14bff6
4 changed files with 236 additions and 227 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@layui/layui-vue", "name": "@layui/layui-vue",
"version": "1.5.0", "version": "1.5.1-alpha.1",
"author": "就眠儀式", "author": "就眠儀式",
"license": "MIT", "license": "MIT",
"description": "a component library for Vue 3 base on layui-vue", "description": "a component library for Vue 3 base on layui-vue",

View File

@ -16,6 +16,8 @@ import {
VNode, VNode,
Component, Component,
watch, watch,
nextTick,
onUnmounted
} from "vue"; } from "vue";
import { LayIcon } from "@layui/icons-vue"; import { LayIcon } from "@layui/icons-vue";
import LayInput from "../input/index.vue"; import LayInput from "../input/index.vue";
@ -69,18 +71,34 @@ const singleValue = ref("");
const multipleValue = ref([]); const multipleValue = ref([]);
const emits = defineEmits<SelectEmits>(); const emits = defineEmits<SelectEmits>();
const openState: Ref<boolean> = ref(false); const openState: Ref<boolean> = ref(false);
const selectedItem: Ref<any> = ref([]);
const options = ref<any>([]); const options = ref<any>([]);
var timer: any;
onMounted(() => { const getOption = (nodes: VNode[]) => {
nodes?.map((item: VNode) => {
let component = item.type as Component;
if (component.name === LaySelectOption.name) {
options.value.push(item.props);
} else {
getOption(item.children as VNode[]);
}
});
};
const intOption = () => {
if (slots.default) { if (slots.default) {
getOption(slots.default()); getOption(slots.default());
} }
Object.assign(options.value, props.items); Object.assign(options.value, props.items);
}
onMounted(() => {
intOption();
timer = setInterval(intOption, 500);
watch( watch(
selectedValue, [selectedValue, options],
() => { () => {
if (multiple.value) { if (multiple.value) {
multipleValue.value = selectedValue.value.map((value: any) => { multipleValue.value = selectedValue.value.map((value: any) => {
@ -98,20 +116,13 @@ onMounted(() => {
})?.label; })?.label;
} }
}, },
{ immediate: true } { immediate: true, deep: true }
); );
}); });
const getOption = function (nodes: VNode[]) { onUnmounted(() => {
nodes?.map((item: VNode) => { clearInterval(timer);
let component = item.type as Component; })
if (component.name === LaySelectOption.name) {
options.value.push(item.props);
} else {
getOption(item.children as VNode[]);
}
});
};
const selectedValue = computed({ const selectedValue = computed({
get() { get() {
@ -141,7 +152,6 @@ const handleClear = () => {
}; };
provide("openState", openState); provide("openState", openState);
provide("selectedItem", selectedItem);
provide("selectedValue", selectedValue); provide("selectedValue", selectedValue);
provide("searchValue", searchValue); provide("searchValue", searchValue);
provide("multiple", multiple); provide("multiple", multiple);
@ -218,3 +228,4 @@ provide("multiple", multiple);
</lay-dropdown> </lay-dropdown>
</div> </div>
</template> </template>

View File

@ -28,7 +28,6 @@ const props = withDefaults(defineProps<LaySelectOptionProps>(), {
label: "", label: "",
}); });
const selectedItem: Ref<any> = inject("selectedItem") as Ref<any>;
const openState: Ref<boolean> = inject("openState") as Ref<boolean>; const openState: Ref<boolean> = inject("openState") as Ref<boolean>;
const selectedValue: WritableComputedRef<any> = inject( const selectedValue: WritableComputedRef<any> = inject(
"selectedValue" "selectedValue"
@ -53,21 +52,14 @@ const selected = computed(() => {
}); });
const select = () => { const select = () => {
const info = {
label: props.label,
value: props.value,
dispabled: props.disabled,
keyword: props.keyword,
};
if (multiple.value) { if (multiple.value) {
if (Array.isArray(selectedItem.value)) { if (Array.isArray(selectedValue.value)) {
if (notChecked.value) selectedItem.value.push(info); if (notChecked.value) selectedValue.value.push(props.value);
} else { } else {
selectedItem.value = [info]; selectedValue.value = [props.value];
} }
} else { } else {
selectedItem.value = info; selectedValue.value = props.value;
} }
}; };
@ -80,8 +72,8 @@ const display = computed(() => {
const notChecked = computed(() => { const notChecked = computed(() => {
return ( return (
selectedItem.value.find((item: any) => { selectedValue.value.find((item: any) => {
return item.value === props.value; return item === props.value;
}) === undefined }) === undefined
); );
}); });

View File

@ -183,7 +183,7 @@ export default {
::: demo ::: demo
<template> <template>
<lay-select v-model="selected2" :multiple="true"> <lay-select v-model="selected2" :multiple="true">
<lay-select-option v-for="index of 200" :value="index" :label="index"></lay-select-option> <lay-select-option v-for="index of count2" :value="index" :label="index"></lay-select-option>
</lay-select> </lay-select>
</template> </template>
@ -193,9 +193,15 @@ import { ref } from 'vue'
export default { export default {
setup() { setup() {
const count2 = ref(0)
const selected2 = ref([1]) const selected2 = ref([1])
setTimeout(() => {
count2.value = 100;
}, 2000);
return { return {
count2,
selected2 selected2
} }
} }