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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值