🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
>[success] # props -- defineProps Ts 版本 * `defineProps ` 在ts 版本支持 **泛型参数来定义 prop** * 传递给`defineProps`的泛型参数本身**不能**是一个导入的类型 * 基于类型的声明或者运行时声明都可以使用,但是你不能同时使用两者 * 接口或对象字面类型可以包含从其他文件导入的类型引用 * ts 类型编译时候 require 默认不是false 是true 1. **泛型参数来定义 prop** ~~~ <template> {{ props.name }} </template> <script setup lang="ts"> // js 版本使用支持的 // const props = defineProps({ // name: String, // }); // 类型字面量定义 // type Props = { // name: string; // age: number | string; // }; // ts 泛型形式定义 interface Props { name: string; age?: number | string; } const props = defineProps<Props>(); </script> <style></style> ~~~ 2. 传递给`defineProps`的泛型参数本身**不能**是一个导入的类型 ~~~ import { Props } from './other-file' // 不支持! defineProps<Props>() ~~~ 3. 基于类型的声明或者运行时声明都可以使用,但是你不能同时使用两者 ~~~ <template> <div></div>{{ props.name }} </template> <script setup lang="ts"> // 不可以两种写法混用 type Props = { name: string; age: number | string; }; const props = defineProps<Props>({ name: String, }); </script> <style></style> ~~~ 4. 接口或对象字面类型可以包含从其他文件导入的类型引用 ~~~ type a = string; export default a; ~~~ ~~~ <template> <div></div>{{ props.name }} </template> <script setup lang="ts"> import a from '../Props/props'; // 接口中调用的类型可以从 其他文件导入 type Props = { name: a; // 我使用其他文件类型 age: number | string; }; const props = defineProps<Props>(); </script> <style></style> ~~~ 5. ts 类型编译时候 require 默认不是false 是true `defineProps<{ msg: string }>`会被编译为`{ msg: { type: String, required: true }}`。 ![](https://img.kancloud.cn/b4/3d/b43d7135b2cf177ffff9704b2cd01fad_518x138.png) >[danger] ##### ts 泛型参数来定义 -- 定义默认值 ~~~ interface Props { msg?: string // ? 相当于 require 是否必填默认必填 labels?: string[], age:12 | 13, // 相当于 validator,但复杂的不行 } // 定义默认值比较复杂 需要withDefaults 函数 const props = withDefaults(defineProps<Props>(), { msg: 'hello', labels: () => ['one', 'two'] }) ~~~ >[danger] ##### ts 泛型参数来定义 -- 开启响应式语法糖 这种形式必须是**开启响应式语法糖**,默认是关闭的目前在实验属性,需要版本 [可以参考](https://staging-cn.vuejs.org/guide/extras/reactivity-transform.html#explicit-opt-in) `vue@^3.2.25`。 ### Vite[#](https://staging-cn.vuejs.org/guide/extras/reactivity-transform.html#vite) * 需要`@vitejs/plugin-vue@^2.0.0` * 应用于 SFC 和 js(x)/ts(x) 文件。在执行转换之前,会对文件进行快速的使用检查,因此不使用宏的文件应该不会有性能损失。 * 注意`refTransform`现在是一个插件的顶层选项,而不再是位于`script.refSugar`之中了,因为它不仅仅只对 SFC 起效。 ~~~ // vite.config.js export default { plugins: [ vue({ reactivityTransform: true }) ] } ~~~ ### `vue-cli`[#](https://staging-cn.vuejs.org/guide/extras/reactivity-transform.html#vue-cli) * 目前仅对 SFC 起效 * 需要`vue-loader@^17.0.0` ~~~ // vue.config.js module.exports = { chainWebpack: (config) => { config.module .rule('vue') .use('vue-loader') .tap((options) => { return { ...options, reactivityTransform: true } }) } } ~~~ ### 仅用`webpack`+`vue-loader`[#](https://staging-cn.vuejs.org/guide/extras/reactivity-transform.html#plain-webpack-vue-loader) * 目前仅对 SFC 起效 * 需要`vue-loader@^17.0.0` ~~~ // webpack.config.js module.exports = { module: { rules: [ { test: /\.vue$/, loader: 'vue-loader', options: { reactivityTransform: true } } ] } } ~~~ * 开启后使用 ~~~ <script setup lang="ts"> interface Props { msg: string count?: number foo?: string } const { msg, // 默认值正常可用 count = 1, // 解构时命别名也可用 // 这里我们就将 `props.foo` 命别名为 `bar` foo: bar } = defineProps<Props>() watchEffect(() => { // 会在 props 变化时打印 console.log(msg, count, bar) }) </script> ~~~