为 props 标注类型
当使用
1 2 3 4 5 6 7 8 9 | <script setup lang= "ts" > const props = defineProps({ foo: { type: String, required: true }, bar: Number }) props.foo // string props.bar // number | undefined </script> |
这被称为 运行时声明 ,因为传递给 defineProps() 的参数会作为运行时的 props 选项使用。
第二种方式,通过泛型参数来定义 props 的类型,这种方式更加直接:
1 2 3 4 5 6 | <script setup lang= "ts" > const props = defineProps<{ foo: string bar?: number }>() </script> |
这被称为 基于类型的声明 ,编译器会尽可能地尝试根据类型参数推导出等价的运行时选项。
我们也可以将 props 的类型移入一个单独的接口中:
1 2 3 4 5 6 7 8 | <script setup lang= "ts" > interface Props { foo: string bar?: number } const props = defineProps<Props>() </script> |
基于类型的方式更加简洁,但失去了定义 props 默认值的能力。我们可以通过目前实验性的 响应性语法糖 来解决:
1 2 3 4 5 6 7 | <script setup lang= "ts" > interface Props { foo: string bar?: number } // 响应性语法糖 默认值会被编译为等价的运行时选项 const { foo, bar = 100 } = defineProps() |
这个行为目前需要在配置中显式地选择开启:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // vite.config.js export default { plugins: [ vue({ reactivityTransform: true }) ] } // vue.config.js module.exports = { chainWebpack: (config) => { config.module .rule( 'vue' ) .use( 'vue-loader' ) .tap((options) => { return { ...options, reactivityTransform: true } }) } } |
如果没有使用
1 2 3 4 5 6 7 8 9 | import { defineComponent } from 'vue' export default defineComponent({ props: { message: String }, setup(props) { props.message // <-- 类型:string } }) |