vue 组件间通信

494 阅读3分钟

常用方法

1、父组件向子组件传值 通过属性传值,引入子组件,绑定属性 :属性名 或 v-bind:属性名,子组件通过props接收传递过来的值 2、子组件向父组件传值 通过 this.$emit将事件和参数传递给父组件 3、父组件调用子组件方法 (a): 给子组件加一个ref引用,父组件通过this.$refs即可找到该子组件,也可以操作子组件的方法:this.$refs.ref名.子组件方法;
(b): 通过$children,可以获 取到所有子组件的集合:this.children[0].方法 $children 实例 property 已从 Vue 3.0 中移除,不再支持。

4、子组件调用父组件方法 通过$parent可以找到父组件,进而调用其方法:this.$parent.父组件方法 5、平级组件间通信 (a): 创建一个公共文件eventBus.js,只是创建一个空的vue实例 export default new Vue();通过eventBus.$emit()传递事件和参数,通过eventBus.$on()接收事件和参数。 $on$off$once 实例方法已被移除,应用实例不再实现事件触发接口。可以使用实现了事件触发接口的外部库来替换现有的 event hub,例如 mitt 或 tiny-emitter。


(b): 使用vuex

其他方法

1、.sync修饰符update:myPropName 的模式触发事件,如:在一个包含 name prop 的假设的子组件中,我们可以用以下方法表达对其赋新值的意图: this.$emit('update:name', newName) 然后父组件可以监听那个事件并根据需要更新一个本地的数据 property(title,父组件属性),这样就通过更新子组件属性name从而更新了父组件属性title

<child
  v-bind:name="title"
  v-on:update:name="title = $event"
></child>

使用sync简写后为: <child :name.sync="title"></child>


PS: 注意带有 .sync 修饰符的 v-bind 不能和表达式一起使用 (例如 v-bind:name.sync=”title + ‘!’” 是无效的)。取而代之的是,你只能提供你想要绑定的 property 名,类似 v-model。 当我们用一个对象同时设置多个 prop 的时候,也可以将这个 .sync 修饰符和 v-bind 配合使用: <child v-bind.sync="object对象"></child> 这样会把 object 对象中的每一个 property (如 title) 都作为一个独立的 prop 传进去,然后各自添加用于更新的 v-on 监听器。 将 v-bind.sync 用在一个字面量的对象上,例如 v-bind.sync=”{ title: doc.title }”,是无法正常工作的,因为在解析一个像这样的复杂表达式的时候,有很多边缘情况需要考虑。

2、provide/inject provideinject 主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的上下文特性很相似。 例如:实现一个刷新页面的功能(reload方法),在根组件中

provide() {
    return {
        reload: this.reload
    }
}

并在methods中实现reload方法;在子孙组件中,inject: ['reload'],使用时直接调用即可(this.reload())。

3、$root 当前组件树的根Vue实例,如果当前实例没有父实例,此实例将会是自己。通过访问根组件也能进行数据之间的交互,但极小情况下会直接修改父组件中的数据。

4、 attrs 和 listeners vm.$attrs 包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (classstyle 除外)。当一个组件没有声明任何prop 时,这里会包含所有父作用域的绑定 (classstyle 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。 简单点讲就是包含了所以父组件在子组件上设置的属性(除了prop传递的属性、class style )。 概念理解:主要用于跨层级(多层级,一般多于两层)传递数据。数据传递方向是:自上而下,grandpa组件-->father组件-->son组件grandpa组件props(如:name,title),引入father组件,father组件传递grandpa组件的属性nametitle<father :name="name" :title="title"></father>;然后在father组件中,引入son组件,<son v-bind="$attrs"></son>;最后在son组件中使用从grandpa传递过来的属性this.$attrs.name & this.$attrs.title
PS:(a)、大于等于三层才有实际意义;(b)、不传递样式属性;(c)、$attrs只获取继承来的属性;(d)、子组件声明了同样的属性后$attrs会自动剔除该属性;



vm.$listeners包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。简单点讲它是一个对象,里面包含了作用在这个组件上所有的监听器(监听事件),可以通过 v-on="$listeners" 将事件监听指向这个组件内的子元素(包括内部的子组件)。 概念理解:基本路数参照$attrs,但是事件和参数传递方向相反,即从son-->father-->grandpa;



inheritAttrs默认情况下父作用域的不被认作 props 的特性绑定 (attribute bindings) 将会“回退”且作为普通的 HTML 特性应用在子组件的根元素上。当撰写包裹一个目标元素或另一个组件的组件时,这可能不会总是符合预期行为。通过设置 inheritAttrsfalse,这些默认行为将会被去掉。而通过 (同样是 2.4 新增的) 实例属性 $attrs 可以让这些特性生效,且可以通过 v-bind 显性的绑定到非根元素上。 概念理解:控制台DOM不想看继承的属性时,该项值设置为false隐藏即可。

以上是vue2 attrs 和 listeners用法。vue3移除listeners,并且把listeners放在attrs里面,style和class也包含在attrs内。