Vue3实战笔记(32)—组件传值props第三天还很细


前言

Vue 组件可以更细致地声明对传入的 props 的校验要求。比如我们上面已经看到过的类型声明,如果传入的值不满足类型要求,Vue 会在浏览器控制台中抛出警告来提醒使用者。这在开发给其他开发者使用的组件时非常有用。


一、Prop 校验

要声明对 props 的校验,你可以向 defineProps() 宏提供一个带有 props 校验选项的对象,例如:


defineProps({
  // 基础类型检查
  // (给出 `null` 和 `undefined` 值则会跳过任何类型检查)
  propA: Number,
  // 多种可能的类型
  propB: [String, Number],
  // 必传,且为 String 类型
  propC: {
    type: String,
    required: true
  },
  // Number 类型的默认值
  propD: {
    type: Number,
    default: 100
  },
  // 对象类型的默认值
  propE: {
    type: Object,
    // 对象或数组的默认值
    // 必须从一个工厂函数返回。
    // 该函数接收组件所接收到的原始 prop 作为参数。
    default(rawProps) {
      return { message: 'hello' }
    }
  },
  // 自定义类型校验函数
  // 在 3.4+ 中完整的 props 作为第二个参数传入
  propF: {
    validator(value, props) {
      // The value must match one of these strings
      return ['success', 'warning', 'danger'].includes(value)
    }
  },
  // 函数类型的默认值
  propG: {
    type: Function,
    // 不像对象或数组的默认,这不是一个
    // 工厂函数。这会是一个用来作为默认值的函数
    default() {
      return 'Default function'
    }
  }
})

注意: defineProps() 宏中的参数不可以访问 <script setup> 中定义的其他变量,因为在编译时整个表达式都会被移到外部的函数中。
一些补充细节:

  • 所有 prop 默认都是可选的,除非声明了 required: true。
  • 除 Boolean 外的未传递的可选 prop 将会有一个默认值 undefined。
  • Boolean 类型的未传递 prop 将被转换为 false。这可以通过为它设置 default 来更改——例如:设置为
    default: undefined 将与非布尔类型的 prop 的行为保持一致。
  • 如果声明了 default值,那么在 prop 的值被解析为 undefined 时,无论 prop 是未被传递还是显式指明的
    undefined,都会改为 default 值。
  • 当 prop 的校验失败后,Vue 会抛出一个控制台警告 (在开发模式下)。
  • 如果使用了基于类型的 prop 声明 ,Vue 会尽最大努力在运行时按照 prop
    的类型标注进行编译。举例来说,defineProps<{ msg: string }> 会被编译为 { msg: { type:
    String, required: true }}

二、运行时类型检查

校验选项中的 type 可以是下列这些原生构造函数:

String

Number

Boolean

Array

Object

Date

Function

Symbol

Error

另外,type 也可以是自定义的类或构造函数,Vue 将会通过 instanceof 来检查类型是否匹配。例如下面这个类:

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName
    this.lastName = lastName
  }
}

你可以将其作为一个 prop 的类型:


defineProps({
  author: Person
})

注意:用class声明的类可以当作属性的类型直接这样用,接口却不行,注意看下面代码的差别:


    interface NavigationItem{
      children: Array<Object>,
        id:string,
        name:string,
        path:string
    }

    class Person {
       firstName = ""
       lastName = ""
      constructor(firstName:string, lastName:string) {
          this.firstName = firstName
          this.lastName = lastName
      }
    }


    //这种方式会报错,同理,Type声明的类型也不能
    defineProps({
      navigationItem :NavigationItem,//“NavigationItem”仅表示类型,但在此处却作为值使用。ts(2693)
      author: Person,
      book:shtype//“shtype”仅表示类型,但在此处却作为值使用。ts(2693
    })

    //使用interface Type做类型可以使用这种方式
    const {navigationItem} = defineProps<{
      navigationItem :NavigationItem,
      author: Person,
      book:shtype
    }>()

再看一个有意思的接口定义,会不会对声明类型有一点点启发?:

 interface NavigationItem{
      children: Array<NavigationItem>,
        id:string,
        name:string,
        path:string,
        child:{
          id:string,
          name:string,
          path:string,
          child:{}
        }
    }

三、Boolean 类型转换

为了更贴近原生 boolean attributes 的行为,声明为 Boolean 类型的 props 有特别的类型转换规则。以带有如下声明的 组件为例:


defineProps({
  disabled: Boolean
})

该组件可以被这样使用:


<!-- 等同于传入 :disabled="true" -->
<MyComponent disabled />

<!-- 等同于传入 :disabled="false" -->
<MyComponent />

当一个 prop 被声明为允许多种类型时,Boolean 的转换规则也将被应用。然而,当同时允许 String 和 Boolean 时,有一种边缘情况——只有当 Boolean 出现在 String 之前时,Boolean 转换规则才适用:


// disabled 将被转换为 true
defineProps({
  disabled: [Boolean, Number]
})

// disabled 将被转换为 true
defineProps({
  disabled: [Boolean, String]
})

// disabled 将被转换为 true
defineProps({
  disabled: [Number, Boolean]
})

// disabled 将被解析为空字符串 (disabled="")
defineProps({
  disabled: [String, Boolean]
})

总结

本文很细,基于官方文档的解读,注意文中强调的注意事项,都是实际应用时候的心得体会,每个注意事项都是示例验证过,放心享用。

心若没有栖息的地方,到哪里都是在流浪。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值