组件之间传值的方式:
1、props + $emit
父组件定义需要传给子组件的属性值 <Child :name="a" :value="11" v-on:change="changeValue" />
子组件使用props接收数据 props:[ 'name', 'value' ] ;使用$emit向父组件传递数据 this.$emit('change', 22);
2、$attrs 与 $listeners
父组件传值给子组件,子组件再传给它的子组件;这种方式在简单的层级关系可以使用,但如果层级比较多,就会很乱。
在vue2.4之后新增了$attrs 与 $listeners;解决了层级关系组件传值与调用的问题
下面以层级组件A、B、C为例:
一般情况下,如果组件A绑定的属性:a="1" :b="2"没有在组件B中使用props接收,那么这些属性会生成类似于<div a='1' b='2'>的节点展示在B的根节点上,如果在 组件B设置了inheritAttrs:false(禁用继承属性),会取消这种属性的继承;同时在当前组件引用的组件C中使用v-bind="$attrs"可以将组件的这些未绑定到props的属性值传递给下一级组件;此时,最后一层组件就可以使用父组件的属性值了。
如果组件C想要直接调用跨层级组件A的方法,可以在B组件调用C组件时定义一个v-on="$listeners",在A组件监听事件,即可直接调用A组件的方法。
3、事件总线eventBus
组件之间互相调用的时候,使用父子组件传值的方式不能满足需求;可以建造一个事件中心Bus,调用Bus.$emit传数据,Bus.$on监听数据变化;
新建一个Bus.js,引入Vue,创建一个空的Vue对象,在需要的地方引入js,或者将这个js绑定到vue的原型上;使用Bus.$emit()传值;使用Bus.$on监听;
最后,记住在调用$on的组件中销毁Bus,否则在不刷新页面的情况下会一直调用: beforeDestory(){ Bus.$off }。
4、$parent 与 $children
直接使用this.$parent.msg = '11'来修改父组件的msg
使用this.$children[0].msg = '22' 来修改第一个子组件的msg
5、provide 与 inject
在父组件中使用provide:{ a: 1 } 来分发数据;在子组件中使用inject: [ 'a' ] 来接收数据;只要子组件在父组件的生命周期当中,就可以拿到数据,不论有多少层级。
6、v-model
父组件通过v-model传值给子组件,会自动传递一个字段为value的props属性;在子组件直接可以用props接收value;
同时,可以在子组件中使用this.$emit('input', ''修改的值') 通过这种方式直接修改父组件的value,此时父组件的value就可以响应式的改变了。
7、vuex 与 storage
如果需要共享的数据比较多,可以使用vuex或者缓存的方式来进行组件之间的数据共享。
8、ref
在组件调用时设置一个ref="childone",此时可以使用this.$refs.childone.clickFunc(‘111’) 来调用子组件的方法。
适用场景:
1、父子组件
(1) props $emit
(2) $parent $children
(3) $attrs $listeners
(4) v-model
(5) ref
(6) provide inject
2、兄弟组件
(1) bus
(2) vuex storage
3、跨级组件
(1) bus
(2) vuex
(3) $attrs $listeners
(4) provide inject