文章目录
这里是完整的目录图片,由于整篇文章篇幅太长,拆分成了几篇来展示
10. 针对 TypeScript 的功能
1.针对类型的 props/emit 声明
在 Vue3 setup script 语法糖当中,声明 props 和 emit 选项时是通过 defineProps 以及 defineEmits 来声明的
- 运行时声明 : defineProps 和 defineEmits 在 Vue3 语法糖中的方式是
运行时声明
- 类型声明 : 针对 TypeScript , Vue3 setup 语法糖还支持
类型声明
defineProps 和 defineEmits 选项.
但是需要注意运行时声明和类型声明这两种声明方式只能二选一
,不能同时使用,否则编译报错
运行时声明 defineProps 和 defineEmits 选项的写法
父组件代码
<!-- father.vue -->
<template>
<div>
<h2>我是父组件!</h2>
<Child foo="使用子组件通过 props 传值 ! " @change="fnInFather" @hello = "fnInFather2"></Child>
</div>
</template>
<script setup>
import Child from './child.vue'
const fnInFather = (msg)=>{
console.log("父组件的 fnInFather 函数触发了,拿到了后面的消息====>",msg)
}
const fnInFather2 = (msg)=>{
console.log("父组件的 fnInFather2 函数触发了,拿到了后面的消息====>",msg)
}
</script>
子组件代码
<template>
我是子组件!
<div>从父组件传过来的 foo : {
{ foo }}</div>
<div @click="fnInChild()">点击我触发父组件绑定的 change 事件</div>
<div @click="emit('change', '我是来自子组件的数据')">点击我触发父组件绑定的 change 事件</div>
<div @click="emit('hello', '我是来自子组件的数据')">点击我触发父组件绑定的 hello 事件</div>
</template>
// 运行时声明 defineProps 和 defineEmits 选项
<script setup>
const props = defineProps({
foo: String,
bar: String,
});
const emit = defineEmits(['change', 'hello']);
</script>
defineProps 对将要传入组件的值进行类型限制 , 这个限制是在运行的时候执行的
运行时声明的方式 — 即使传入组件的值的类型和组件内声明限制的类型不同 在编译器也不会报错,运行的时候会在控制台报错
控制台报错
类型声明 defineProps 和 defineEmits 选项的写法
这里的类型声明 我理解为 是编译时声明
类型声明 defineProps 以及 defineEmits 是编译时类型检测,利用的是 vue 支持 ts 的特性
注意使用类型声明是需要在 script 标签中声明 lang = "ts"
来使用 ts 的特性对 props emits 进行类型限制
和上面的代码 (只有子组件的 Script 代码有改动)
// 类型声明 defineProps 和 defineEmits 选项
<script setup lang="ts">
const props = defineProps<{
foo: string
bar?: number
}>()
const emit = defineEmits<{
(e: 'change', id: string): void
(e: 'hello', value: string): void
}>()
const fnInChild = () => {
console.log('子组件的点击事件触发了');
emit('change', '我是来自子组件的数据');
};
</script>
似乎是通过 ts 中的泛型约束来实现对 props emits 类型的限制的, ts 的类型检测是在编译过程中进行的,所以如果类型检测不一致的话,会在编译时报错无法执行 (这里尝试了下,它在控制台报了错,还是顺利执行了)
运行时声明和类型声明不能同时使用
defineProps 或 defineEmits 要么使用运行时声明,要么使用类型声明。同时使用两种声明方式会导致编译报错。[vite] Internal server error: [@vue/compiler-sfc] Identifier 'props' has already been declared. (9:8)
2.使用类型声明时的默认 props 值
首先来看下我们使用运行时声明 props 的时候怎样配置参数是否是必传项,以及默认值
父组件
<!-- father.vue -->
<template>
<div>
<h2>我是父组件!</h2>
<Child foo="使用子组件通过 props 传值 ! " :bar="2023"></Child>
</div>
</template>
<script setup>
import Child from './child.vue'
</script>
子组件
<!-- child.vue -->
<template>
我是子组件!
<div>从父组件传过来的 foo : {
{ foo }}</div>
<div>从父组件传过来的 bar : {
{ bar }}</div>
</template>
<script setup>
const props = defineProps({
foo: {
type : String,
required : true,
},
bar:{
type : String,
required : false,
default : '我是 foo 参数的默认值'
},
});
</script>
当我们使用 ts 编译时检测类型的方法,应当怎样同时完成配置默认值呢 ?
defineProps 声明无法给 props 提供默认值,我们可以使用 withDefault ,withDefault 是 vue3 当中封装的一个宏指令, withDefault 不需要引入,可以直接使用
<script setup lang="ts">
const props = withDefaults(defineProps<{
foo: string
bar?: string
}>(),{
bar:'我是 bar 参数的默认值 ~~ '
})
</script>
总结
以上就是在学习 Vue3 setup 语法糖中的理解记录,如果又不正确的地方,欢迎各位指正,有疑问的小伙伴也可以评论区相互交流吖 ~
vue3 script setup 语法糖用了才知道有多爽 (一)
vue3 script setup 语法糖用了才知道有多爽 (二)
vue3 script setup 语法糖用了才知道有多爽 (三)
vue3 script setup 语法糖用了才知道有多爽 (四)
vue3 script setup 语法糖用了才知道有多爽 (五)