关于在vue3使用ts,父组件如何给子组件的props指定类型?

比如这种情况,
一个表单组件,有一个formValue的props,父组件如何给调用子组件时指定formValue的类型,就是说这个UserFrom是父组件传给子组件的,不是在子组件写死的,不同表单的类型肯定会不一样,就比如用户表单和配置表单,完全不一样

image.png

import { defineComponent } from "vue";
import type { PropType } from "vue";
interface UserFrom {
  name: string;
  age: number;
  sex: string;
}
interface ConfigFrom {
  url: string;
  ip: string;
  port: number;
}
export default defineComponent({
  props: {
    formValue: {
      // 提供相对 `Object` 更确定的类型
      // type: Object as PropType<ConfigFrom>,
      type: Object as PropType<UserFrom>,
      required: true,
    },
  },
});

官网demo连接

阅读 9.2k
2 个回答

泛型了解一下

父组件作为子组件的使用方,应该去匹配子组件声明的类型,而不是想办法去改变它。

而子组件作为一个组件,其内部行为是一定的,这个行为可能依赖于输入的参数(Props),但其 Props 也应该具备一定的数据结构。所以只需要约束需要的数据结构就行,就像问题中的 UserForm 那样。

如果说你的子组件需要做得足够灵活,不管父组件给出什么样的数据都能处理 —— 那就是说,它不需要约束 Props 的类型。既然不需要约束,那父组件指定这个类型又有什么意义呢?父组件内部定义的不管是 UserForm 还是 ConfigForm,子组件都把它当作 Object 来处理,动态分析其数据结构,找需要的数据进行处理,也类型无关。

如果说约束这两种类型都可以传入,那可以把参数类型申明为 PropType<UserForm | ConfigForm>,子组件内部代码根据数据结构特征值来判断传入的是哪种类型(使用类型断言函数),再进行进一步的操作。


示例:子组件

本来想去 SFC Playground 做一个在线的示例,但是好像它对 TypeScript 支持不太好,这个示例是本地编译过测试过的。
image.png
<script lang="ts">
import { defineComponent, type PropType } from "vue";

export interface UserForm {
    name: string;
    age: number;
}

export interface ConfigForm {
    ip: string;
    port: number;
}

function isConfigForm(form: UserForm | ConfigForm): form is ConfigForm {
    return "ip" in form;
}

export default defineComponent({
    props: {
        formValue: {
            type: Object as PropType<UserForm | ConfigForm>,
            required: true,
        }
    },
    computed: {
        isConfig() {
            return isConfigForm(this.formValue);
        },
        stringValue() {
            const value = this.formValue;
            return isConfigForm(value) ? value.ip : value.name;
        }
    }
});
</script>

<template>
    <h2 v-if="isConfig">In Comp: Config Form</h2>
    <h2 v-else>In Comp: User Form</h2>
    <div>{{ stringValue }}</div>
</template>
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题