1、vuex
不论是父子关系、兄弟关系、层层嵌套关系还是八竿子打不着的关系,都可以使用vuex来进行数据的传递或是做做中间处理。
vuex是vue的状态管理器,存储的数据是响应式的,但是并不会保存起来,刷新之后就回到了初始状态,一般在vuex里数据改变的时候存一份到localStorage或sessionStorage里面(看项目需求),刷新之后,如果localStorage里有保存的数据,取出来再替换store里的state即可。
2、事件总线EventBus
通过新建一个js文件event-bus.js,引入vue, new一个vue实例EventBus再导出;然后其他文件中引入EventBus,就可以使用EventBus.$emit发送消息、EventBus.$on来监听接收消息。
几乎可以满足任意场景的数据传递,逻辑比较复杂项目庞大的还是乖乖的用vuex。
3、父子关系
父组件A中通过v-bind(一般使用缩写“:
”)绑定prop传值给子组件B,子组件B使用props接收来自父组件A的数据,prop必须在子组件B中声明,未声明的prop会出现在B组件的$attrs中且dom中能看到该属性(被绑定成了普通的attribute),而已声明的prop则会出现在B组件的$props中且dom中看不到该属性。
子组件B向父组件通信使用$emit方法来触发父组件A中通过v-on(一般使用缩写“@
”)绑定的事件监听器,当然触发的时候可以传值。
ps:父组件通过v-model
传值给子组件时,会自动传递一个value的prop属性,子组件中通过this.$emit('input', val)
来修改父组件中v-model绑定的值。一般常用此方法来实现自定义的双向绑定。
当父组件绑定的prop在子组件中未声明时,在子组件中可以使用$attrs来获取这些属性值;
父组件绑定的(不含.native
修饰器的)事件监听器可以使用$listeners获取到并调用
在父组件中给调用的子组件绑定一个ref假设取名为xxx,然后就可以使用$refs.xxx
来访问到该子组件实例,从而获取其data或调用方法等。
$children获取到的是父组件引用的所有直接子组件的集合(所以它是一个数组),在父组件A中可以使用它来获取到其调用的所有子组件的各种信息。
$parent获取到的是父组件示例,在子组件B中可以使用它来获取其父组件的相关信息。
4、父子孙关系
子组件可以通过$props将父组件的props一起传给孙组件、$attrs来传递子组件中未经声明的props、$listeners来传递父组件的监听器。
父组件调用子组件:
<Son msg="HelloWorld" :data="[1,2,3]" @mylistener="doSth" />
子组件调用孙组件:
<Grandson v-bind="$attrs" /> <Grandson v-bind="$props" /> <Grandson v-bind="{...$props, ...$attrs}" /> <Grandson v-bind="{...$props, ...$attrs}" v-on="$listeners" />
子组件和孙组件中都可以使用this.$emit('mylistener', val)
来触发父组件中的doSth
方法。
5、兄弟组件之间的方法调用
假设父组件中使用了两个组件Brother1、Brother2
<Brother1 ref="brother1" /> <Brother2 ref="brother2" />
需要在Brother2中调用Brother1的方法假定为method1,可以使用
this.$parent.$refs.brother1.method1()
或者
const arr = this.$parent.$children for(let i=0; i<arr.length; i++) { if (arr[i].$options.name === 'Brother1的name') { arr[i].method1() break } }
另外还可以使用eventBus,在Brother2中eventBus.$emit('tel')
,Brother1中
eventBus.$on('tel', () => { this.method1() })
另外使用vuex配合watch也可以实现,定义一个特定的state假设为test,每次需要调用的时候commit改变test的值(可以使用时间戳),Brother2中监听test的值是否发生变化,发生变化就调用method1方法。
6、后记
本文仅记录vue的常用通信方式(例如还有provide/inject等方式)且仅做简述,各种方法的细节或详细使用请查阅官方文档或度娘谷歌。
有朋自远方来...评论一下呗O(∩_∩)O