Vue 父子组件通信的几种方式
场景:子组件中的方法在子组件中并没有调用,而是在父组件中使用 ref 调用子组件的方法;这是一种不怎么常见的父子组件通信,所以趁此机会,整理一下所有的父子组件通信,涨下见识
参考:
问题出现原因:
不够了解多种形式:如 props、$emit
/$on
、vuex、$parent
/ $children
、$attrs
/$listeners
和 provide/inject
结论:
最常用的肯定是 props
,以及 $emit
和 $on
方法,这次在业务中碰到的是 ref
直接调用子组件的方法,在抽离单一方法的子组件时可以使用。
详细了解下多种解决方案:
父组件–> | 子组件 | |
---|---|---|
props | <child :user="data"></child> 先在父组件中绑定变量 |
props:{user:{type:Array,default:()=>[]}} 再在子组件中添加props属性接收父组件传递过来的变量 |
父组件 | <–子组件 | |
在父组件中绑定事件 getChild <child :user="data" @childClick="getChild"></child> |
先在子组件中绑定事件@change="childClick" 触发的时候在事件中用 $emit() 触发父组件中的函数,并将子组件中的变量作为参数传递this.$emit('childClick','canshu'); |
|
$emit/$on(小项目) | 通过一个空的 Vue 实例作为中央事件总线(事件中心 - 全局变量)var Event=new Vue(); Event.$on(事件名,data => {}); |
Event.$emit(事件名,数据); |
vuex | $store.dispatch('action 名称', data1) 来触发;由于 vuex 里,我们保存的状态,都是数组,而 localStorage 只支持字符串,所以需要用 JSON 转换; |
|
$attrs - 收纳属性 $listeners - 收纳事件 |
$attrs :包含了父作用域中不被 prop 所识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。通常配合 interitAttrs 选项一起使用。$listeners :包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件。父组件举例: <child :foo="foo" :boo="boo" :coo="coo" :doo="doo" title="Alice" @one.native="trigger1" @two="trigger2"></child> |
子组件:console.log(this.$attrs); 打印结果: { "boo": "Html", "coo": "CSS", "doo": "Vue", "title": "Alice"} 子组件: console.log(this.$listener); 打印结果: {two:trigger2} 可以直接执行父组件方法: this.$listener.two(); |
provide/inject 主要为高阶插件/组件库提供用例 |
一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。 父组件通过 provider 【和create同级】来提供变量 |
子孙组件中通过 inject 【和props同级】来注入变量。注意:provide 和 inject 绑定并不是可响应的。 |
$parent / $children与 ref | ref:如果在普通的 DOM 元素上使用,引用指向 DOM 元素;如果用在子组件上,引用就指向组件实例,使用后可以直接调用组件的方法或访问数据。 |