vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:
- Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
- 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
安装 npm install vuex --save
使用的时候在main.js中引入
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
学习的最快方法就是看栗子,讲解的最通俗易懂的方法也是举个栗子:
举个栗子.jpg- 1、state
// 如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
···
store.commit('increment')
console.log(store.state.count) // -> 1
- 再次强调,我们通过提交 mutation 的方式改变store.state.count --- (this.$store.state.count)两种方式都可以取到count;
- 由于 store 中的状态是响应式的,在组件中调用 store 中的状态简单到仅需要在计算属性中返回即可。
- 触发变化也仅仅是在组件的 methods 中提交 mutation。
- 2、getters
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
有时候我们需要从 store 中的 state 中派生出一些状态,例如对列表进行过滤并计数:比如这样
computed: {
doneTodosCount () {
return this.$store.state.todos.filter(todo => todo.done).length
}
}
如果有多个页面需要使用到这个filter处理后的数据,那么可以用getters中这么写:
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
然后每个需要用到的这个数据的页面可以通过这种方式取到处理后的数据
store.getters.doneTodos
//或者
this.$store.getters.doneTodos
- 3、mutation
简单的mutation在第一点state里面有提到,可以再仔细推敲一遍
这里要讲的是向 store.commit 传入额外的参数
// ...那么这个n就是传入的参数,state是默认有的
mutations: {
increment (state, n) {
state.count += n
}
}
用commit触发increment改变状态,传入的参数10就是n
store.commit('increment', 10)
另一种对象风格提交方式:当然只掌握前面一种提交方式也是可以的
store.commit({
type: 'increment',
amount: 10
})
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
因为mutation 是同步的:所以就有了action
- 3、action
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
举个栗子
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。
Action 通过 store.dispatch 方法触发:
store.dispatch('increment')
乍一眼看上去感觉多此一举,我们直接分发 mutation 岂不更方便?实际上并非如此,还记得 mutation 必须同步执行这个限制么?Action 就不受约束!我们可以在 action 内部执行异步操作:
actions: {
incrementAsync ({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
- 4、Module
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module),详情请见官网。
官网https://vuex.vuejs.org/zh/guide/
gzh.jpg每日分享前端技术知识,致力于帮助更多前端人翻过一座座山,踏过一个个坑。