管理共享状态
现在有两个页面 A 和 B,还有以下两个要求:
要求它们都能对 count 进行操控。
要求 A 修改了 count 后,B 要第一时间知道,B 修改后,A 也要第一时间知道。
把数据源 count 剥离开来,用一个全局变量或者全局单例的模式进行管理,这样不就在任何页面都可以很容易的取到这个状态了。就是 Vuex 的工作。
具体看官方文档就可以:
vuex安装
当我们的项目不大时,可以使用vuex的简单模式–store模式。
Vuex 的内脏由五部分组成:State、Getter、Mutation、Action 和 Module。在实际应用中,这五个部分并不是必须的,你需要用到什么就添加什么。但是一般再怎么简单的 Vuex,也至少会由 State 和 Mutation 构成。
有时候,我们会发现 State 中的数据,并不是我们直接想要的,如果我们在使用的地方进行处理,那每个使用的地方都需要做改变。这里我们就可以使用getter。
就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
const store = new Vuex.Store({ state: { date: new Date() }, getters: { // Getter 接受 state 作为其第一个参数 weekDate: state => { return moment(state.date).format('dddd'); } } })
另外,Getter 还会将 store.getters 对象暴露出去,你可以以属性的形式访问这些值:
console.log(store.getters.weekDate)
我们可以很容易地在任何组件中使用它:
computed: { weekDate () { return this.$store.getters.weekDate } }
现在需求又变了,每个模块要显示的 weekDate 的格式不一样,有的显示全部日期,有的需要显示星期几,怎么办?
因为 weekDate 并不是一个函数,它仅仅只是一个属性而已。我们就想办法把这个属性变成一个函数:
getters: { // 返回一个函数,就可以传参了 weekDate: (state) => (fm) => { return moment(state.date).format(fm ? fm : 'dddd'); } }
具体使用:
store.getters.weekDate('MM Do YY')
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。mutations必须是同步函数
const store = new Vuex.Store({ state: { count: 1 }, mutations: { // 事件类型 type 为 increment increment (state) { // 变更状态 state.count++ } } })
注意,我们不能直接 store.mutations.increment() 来调用,Vuex 规定必须使用 store.commit 来触发对应 type 的方法:
store.commit('increment')
我们还可以向 store.commit 传入额外的参数:
mutations: { increment (state, n) { state.count += n } } // 调用 store.commit('increment', 10)
这个参数就叫做载荷,在大多数情况下,载荷是一个对象。提交的方式有两种:
// 1、把载荷和type分开提交 store.commit('increment', { amount: 10 }) // 2、整个对象都作为载荷传给 mutation 函数 store.commit({ type: 'increment', amount: 10 })
当我们要修改state里面对象:
const store = new Vuex.Store({ state: { student: { name: '小明', sex: '女' } } })
这个时候,我们如果想要给 student 添加一个年龄 age: 18 属性,怎么办呢?
mutations: { addAge (state) { Vue.set(state.student, 'age', 18) // 或者: // state.student = { ...state.student, age: 18 } } }
上面的mutations必须是同步函数,如果我们需要使用异步,就轮到Action上场了。
Action与mutations不同之处在于:
我们首先来看一个Action示例:
const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } }, actions: { increment (context) { context.commit('increment') } } })
我们也可以通过ES2015的参数表达结构来写: