组件传值

95 阅读3分钟

总结一下我所了解的组件传值方式,方便以后我自己查询。

props

父向子传值最常用的方式,操作相对简单,将需要传递的值以属性的形式传递给子组件,子组件通过 props 接收父组件传递的值。举个例子:

<!--父组件-->
<children :num="childNum"></children>
//子组件
//props数组形式
props: ['num']

//props对象形式1
props: {
  num: Number
}

//props对象形式2
props: {
  num: {
    type: Number,
    default: 0
  }
}

注意:

  1. props 的这三种定义方式只能选择其中的一种,以我个人的习惯我比较倾向于第三种,因为第三种扩展性较好,而且语义更加清晰。
  2. 当然,在一些较为简单的场景下也可以使用第一种与第二种定义方式。除了常用的 typedefault 外,对于父传子的值还可以有其他的属性进行配置,但是这里不会多讲。
  3. props 所接收的值是只读的,如果需要对该值进行修改的话,官方建议是定义一个新的变量并将props 所接收的值赋值给新的变量,在新的变量的基础上进行修改而不是直接修改props 所接收的值。

$emit(event, args)

子向父传值的一种方式就是通过 $emit 实现的,具体的实现是在父组件定义一个监听事件监听子组件,子组件通过 $emit 触发监听事件,然后通过参数的形式向父组件传值。$emit(event, args) 中,event表示触发的监听事件, args 表示子组件传递给父组件的值,可以是多个。具体的实现如示例:

<!--父组件html-->
<!--父组件定义监听事件-->
<children @myFunc="getChild"></children>
//父组件在methods中定义相应的监听函数
//以接收并处理子组件传给父组件的值
getChild(args){
  console.log(args)
}
<!--子组件html-->
<button @click="postChild">给父组件</button>
//子组件js
postChild() {
  this.$emit("myFunc", 123)
}

注意: 根据VUE官网所说:像组件与 prop 一样,事件的名字也提供了自动的格式转换。注意这里我们触发了一个以 camelCase 形式命名的事件,但在父组件中可以使用 kebab-case 形式来监听。与 prop 大小写格式一样,在模板中我们也推荐使用 kebab-case 形式来编写监听器。 但是我在实际使用过程中发现事件的名字并没有自动格式转换。

provide, inject

假设三个组件,分别为爷父孙,我们知道了爷向父传值可以通过 props ,那么爷向孙传值呢?有人会说可以通过爷向父传值,父再向孙传值,说实话,这不失为一种方法。但是如果爷向曾孙、玄孙传值呢?如果继续用 props 传值就会变得很繁琐,而且爷向孙传的值,父不一定需要,我们往往希望一个组件只需要接收自己需要的数据,因此利用props完成上述的传值行为是不太合理也不太方便的。

这时候就轮到 provideinject 出场了,provideinject 被设计用于组件向后代组件进行传值的场景,无论是多远的后代,均可利用 inject 接收 provide 里的值。具体用法看这:依赖注入(provide,inject)

注意: inject 接受的值仍然是只读的。

任意组件传值

可以实现任意组件间传值的方法有许多,写出来将会增加很多的篇幅,因此就不在这里详细写了。我所了解的可以实现任意组件传值的方式有:

  1. vuex
  2. 全局事件总线
  3. localstorage
  4. sesionstorage
  5. 路由传参