非父子组件(跨级组件和兄弟组件)通信时,使用了bus(中央事件总线)的一个方法,用来触发和接收事件,进一步起到通信的作用。
一个组件可以分为数据(model)和视图(view),数据更新时,视图也会自动更新。在视图中又可以绑定一个事件,它们触发methods里指定的方法,从而可以改变数据、更新视图,这是一个组件基本的运行模式。
const store = new Vuex.Store({});
仓库store包含了应用的数据(状态)和操作过程。Vuex里的数据都是响应式的,任何组件使用同一store的数据时,只要store的数据变化,对应的组件也会立即更新。
数据保存在Vuex选项的state字段内。
const store = new Vuex.Store({
state: {
count: 0
}
});
在任何组件内,可以直接通过$store.state.count读取。
<template>
<div>
<h1>首页</h1>
{{$store.state.count}}
</div>
</template>
直接卸载template里显得有点乱,可以用一个计算属性来显示:
<div>
<h1>首页</h1>
{{count}}
</div>
export default {
computed: {
count() {
return $store.state.count;
}
}
}
在组件内来自store的数据只能读取,不能手动修改,修改store中数据的唯一途径是显式地提交mutations。
mutations是Vuex的第二个选项,用来直接修改state里的数据。
在组件内,通过this.$store.commit方法来执行mutations。
mutations还可以接受第二个参数,可以是数字、字符串或对象等类型。
ES6语法
函数的参数可以设定默认值,当没有传入该参数时,使用设置的值。
increment(state,n=1)等同于:
increment(state,n){
n=n||1;
}
提交mutations的另一种方式是直接使用包含type属性的对象。
mutations里尽量不要异步操作数据,否则组件在commit后数据不能立即改变,而且不知道什么时候会改变。
Vuex还有其他3个选项可以使用:getter、actions、modules。
getter能将computed的方法提取出来,也可以依赖其他的getter,把getter作为第二个参数。
action与mutation很像,不同的是action里面提交的是mutation,并且可以一步操作业务逻辑。
action在组件内通过$store.dispatch触发。
modules用来将store分割到不同模块,当项目足够大时,store里的state、getters、mutations、actions会非常多,使用modules可以把它们写到不同的文件中。
module的mutation和getter接收的第一个参数state是当前模块的状态。在actions和getters中还可以接收一个参数rootState,来访问根节点的状态。
vue-bus中央事件总线bus作为一个简单的组件传递事件,用于解决跨级和兄弟组件通信的问题。
vue-bus插件给Vue添加一个属性$bus,并代理$emit、$on、$off三个方法。
ES6语法
emit(event,..args)中的...是函数参数的解构。因为不知道组件会传递多少个参数进来,使用...args可以把从当前参数到最后的参数都获取到。
使用vue-bus有两点需要注意:
$bus.on应该在created钩子内使用,如果在mounted使用,它可能接收不到其他组件来自created钩子内发出的事件;$bus.on在beforeDestroy钩子里应该再使用$bus.off解除,因为组件销毁后,就没有必要把监听的句柄存储在vue-bus中。