likes
comments
collection
share

重学 Vue3 之 props 和事件

作者站长头像
站长
· 阅读数 17

共性

宏观上来说,props 和事件有很多相似的地方。事件使用 v-on 监听事件,emits 选项声明事件,$emit 方法触发事件。props 使用 v-bind 传值,props 选项进行声明,$props 方法获取传值。

重学 Vue3 之 props 和事件

重学 Vue3 之 props 和事件

在上面的例子中。父组件 App 通过 v-bind:name 将 name 传递给子组件,子组件 Coordinate 使用 defineProp 声明将要传入的 name,模版语法可以直接将 name 显示到页面上。点击 hello button 按钮触发 hello 事件,再调用 defineEmits 声明的 sayHi 方法,父组件 v-on:say-hi 监听到事件后弹出弹窗。 可以看出 script setup 环境中 props 和事件使用方式是很相似的。

区别

v-on 和 v-bind 这里不做过多深究,这里重点分析声明和使用的区别。props 和事件声明的时候可以是字符串组数或者是对象。下面是官方 API 中的类型介绍,可以看出 props 有 type,required,default,validator 四个选项用于声明校验,而事件仅有 EmitValidator 函数用于声明校验。

interface ComponentOptions {
  props?: ArrayPropsOptions | ObjectPropsOptions
}

type ArrayPropsOptions = string[]

type ObjectPropsOptions = { [key: string]: Prop }

type Prop<T = any> = PropOptions<T> | PropType<T> | null

interface PropOptions<T> {
  type?: PropType<T>
  required?: boolean
  default?: T | ((rawProps: object) => T)
  validator?: (value: unknown) => boolean
}

type PropType<T> = { new (): T } | { new (): T }[]

interface ComponentOptions {
  emits?: ArrayEmitsOptions | ObjectEmitsOptions
}

type ArrayEmitsOptions = string[]

type ObjectEmitsOptions = { [key: string]: EmitValidator | null }

type EmitValidator = (...args: unknown[]) => boolean

还是通过 script setup 环境来验证类型声明。

重学 Vue3 之 props 和事件

依然使用上面的例子,可以看出 name 可以通过 type,default,required,validator 来进行校验,而 sayHi 只可以通过一个函数进行校验。

props 和 emit 在使用上没有太大的区别。 script setup 环境中 props 通过 defineProps 返回对象的属性进行使用, emit 通过 defineProps 返回的函数进行调用。而在组件实例中,props 被组件实例代理了,因此可以直接通过组件实例进行使用,而 emit 需要使用 $emit 方法进行调用。

重学 Vue3 之 props 和事件

上面的实例中, script setup 环境可以使用 props.name 的形式获取到 props,使用 emit() 的形式调用对应的事件。而在模版中,可以直接访问 name,需要通过 $emit 去调用 sayHi 事件。

结论

Vue3 之后 props 和事件的使用上更加趋于一致,父组件传值或者监听事件,子组件声明,使用 props 或者触发事件。设计思想上一个使用了对象属性,另一个使用了函数。

参考资料:cn.vuejs.org