vue 3.3 泛型和条件属性

问题描述 投票:0回答:1

我正在探索 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>

我正在探索条件输入的想法,但我不知道如何在这种情况下应用它,这可能吗?

typescript vue.js vuejs3 vue-component
1个回答
0
投票

实际上这不是您问题的确切解决方案,而是一种解决方法,毕竟是相同的所需输出

您可以编辑实际组件,使其看起来像这样

<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>

因此,您可以创建两个道具,而不是使用多个道具,一个用于处理数组,另一个用于处理非数组的道具。 希望您觉得这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.