vue3 script setup 语法糖用了才知道有多爽 (六)


这里是完整的目录图片,由于整篇文章篇幅太长,拆分成了几篇来展示
在这里插入图片描述

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 语法糖用了才知道有多爽 (五)

猜你喜欢

转载自blog.csdn.net/YZRHANYU/article/details/129618137