非父子组件(跨级组件和兄弟组件)通信时,使用了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
中。