我正在探索 vue 3.3 上的泛型功能
我有这样的想法:根据另一个 prop 值的值来定义传入 prop 的类型。
这是我的实际组件:
export interface OptionProps {
id: string | number;
name: string;
};
<script setup lang="ts" generic="T extends OptionProps">
import { computed } from "vue";
import {OptionProps} from './types.ts'
// define props by using generic
const props = defineProps<{
options: T[];
modelValue: T | T[];
multiple: boolean;
}>();
// define emits
const emit = defineEmits<{
"update:modelValue": [value: T|T[]];
}>();
// define proxyValue for modelValue to emit update:modelValue
const proxy = computed({
get() {
return props.modelValue;
},
set(value: T|T[]) {
emit("update:modelValue", value);
},
});
</script>
<template>
<div>---- {{ options }} ----- {{ proxy }}</div>
</template>
我想要做的是根据多个值限制 modelValue 的类型,这意味着:
如果 multiple 为 true -> modelValue 应为 T[] 但如果为 false,则 modelValue 应为 T
所以理想情况下,我希望组件的调用者在使用数组 modelValue 和多个 false 调用组件时收到错误:
<script setup lang="ts">
import { ref } from 'vue'
import Comp from './Comp.vue';
import { OptionProps } from './types.ts'
const result = ref<OptionProps[]>([{id: undefined, name: undefined}])
</script>
<template>
<Comp
:model-value="result"
:options="[{id: 1, name: 'one'}, {id: 2, name: 'two'}]"
:multiple="false"
/>
</template>
我正在探索条件输入的想法,但我不知道如何在这种情况下应用它,这可能吗?
实际上这不是您问题的确切解决方案,而是一种解决方法,毕竟是相同的所需输出
您可以编辑实际组件,使其看起来像这样
<script setup lang="ts" generic="T extends OptionProps">
import { computed } from "vue";
import type { OptionProps } from "./types.ts";
// define props by using generic
const props = defineProps<{
options: T[];
singleModelValue?: T;
multiModelValue?: T[];
}>();
// define emits
const emit = defineEmits<{
"update:singleModelValue": [value: T | undefined];
"update:multiModelValue": [value: T[] | undefined];
}>();
// define proxyValue for singleModelValue to emit update:modelValue
const singleProxy = computed({
get() {
return props?.singleModelValue || undefined;
},
set(value: T | undefined) {
emit("update:singleModelValue", value);
},
});
// define proxyValue for multiModelValue to emit update:multiModelValue
const multiProxy = computed({
get() {
return props?.multiModelValue || [];
},
set(value: T[] | undefined) {
emit("update:multiModelValue", value);
},
});
</script>
<template>
<div>---- {{ options }} ----- {{ singleProxy ?? multiProxy }}</div>
</template>
然后像这样使用它
<script setup lang="ts">
import { ref } from "vue";
import Comp from "./components/Comp.vue";
import type { OptionProps } from "./components/types.ts";
const single_result = ref<OptionProps>({ id: 1, name: "hello" });
const multi_result = ref<OptionProps[]>([{ id: 1, name: "hello" }]);
</script>
<template>
<Comp
:single-model-value="single_result"
:options="[
{ id: 1, name: 'one' },
{ id: 2, name: 'two' },
]"
/>
<br />
<Comp
:multi-model-value="multi_result"
:options="[
{ id: 1, name: 'one' },
{ id: 2, name: 'two' },
]"
/>
</template>
因此,您可以创建两个道具,而不是使用多个道具,一个用于处理数组,另一个用于处理非数组的道具。 希望您觉得这有帮助。