在用vue做为前端框架进行开发的时候,对于组件间的传值你必定不会陌生,若是只是简单的父子组件传值,我想你确定不会选择用Vuex来进行状态管理,可是若是你须要构建一个中大型单页应用,组件间数据交互比较复杂频繁,你极可能会考虑如何更好地在组件外部管理状态,那么Vuex 将会成为天然而然的选择。前端
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的全部组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 这是官方的一种说法。vue
用我的的话总结下:Vuex就是为了实现多组件数据共享,从而创建一个叫store的数据管理库,将须要共享的数据存放在里面,在须要的地方能够取出来做为初始数据,也能够在组件内经过dispatch或者提交commit方法来改变该原始数据状态,从而实现的data的共享。vuex
Vuex中的数据源,咱们须要保存的数据就保存在这里,能够在页面经过this.$store.state来获取咱们定义的数据。redux
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const state = {
number: 0
}
export default new Vuex.Store({
state,
});
复制代码
在页面中经过this.$store.state.number 便可获取到当前的值。数组
Vuex 容许咱们在 store 中定义“getter”(能够认为是 store 的计算属性)。就像计算属性同样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被从新计算。promise
Getter 接受 state 做为其第一个参数:缓存
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const state = {
number: 0
}
const getters = {
getNumber(state) {
return state.number + 1
}
}
export default new Vuex.Store({
state,
getters,
});
复制代码
在页面你能够用两种方式取到getters里面的值bash
Getter 会暴露为 store.getters 对象,你能够以属性的形式访问这些值 如: this.$store.getters.getNumber前端框架
Getter 也能够接受其余 getter 做为第二个参数:框架
const state = {
number: 1
}
const getters = {
getNumber(state) {
return state.number + 1 // 2
},
getDoubNUmber(state, getters) {
return state.number + getters.getNumber // 3
}
}
复制代码
注意: getter 在经过属性访问时是做为 Vue 的响应式系统的一部分缓存其中的。
你也能够经过让 getter 返回一个函数,来实现给 getter 传参。在你对 store 里的数组进行查询时很是有用。
const state = {
number: 1,
list: [1, 2, 3, 4, 5]
}
const getters = {
getNumber(state) {
return state.number + 1 // 2
},
getDoubNumber(state, getters) {
return state.number + getters.getNumber // 3
},
filterNumber:(state)=>(num)=> {
return state.list.find(item=> item%num === 0)
}
}
export default new Vuex.Store({
state,
getters,
});
复制代码
注意,getter 在经过方法访问时,每次都会去进行调用,而不会缓存结果 this.$store.getters.filterNumber(3)
更改 Vuex 的 store 中的状态的惟一方法是提交 mutation。Vuex 中的 mutation 很是相似于事件:每一个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是咱们实际进行状态更改的地方,而且它会接受 state 做为第一个参数, 提交载荷(payload) 做为额外的参数,而且在大多数状况下,载荷应该是一个对象,这样能够包含多个字段而且使记录的 mutation 会更易读:
你能够这样写:
const mutations = {
increment(state, n) {
state.number += n
}
}
复制代码
但你不能直接调用一个 mutation handler。这个选项更像是事件注册:“当触发一个类型为 increment 的 mutation 时,调用此函数。”要唤醒一个 mutation handler,你须要以相应的 type 调用 store.commit 方法:
this.$store.commit('increment', 1)
复制代码
也能够这样写:
const mutations = {
increment(state, payload) {
state.number += payload.count
}
}
复制代码
而后:
使用 this.$store.commit('increment', {count: 1}) 提交,
// 或者另外一种方式是直接使用包含 type 属性的对象进行提交:
this.$store.commit({
type: 'increment',
count: 1
})
复制代码
特别说明:在 Vuex 中,mutation 都是同步任务: 为了处理异步操做,让咱们来看一看 Action。
Action 相似于 mutation,不一样在于:
一、Action 提交的是 mutation,而不是直接变动状态。
二、Action 能够包含任意异步操做。
虽然在页面中经过提交commit是能够达到修改store中状态值的目的,可是官方并不建议咱们这样作,而是让咱们去提交一个action,在action中提交mutation再去修改状态值。
const mutations = {
increment(state) {
state.number += 1
}
}
const actions = {
addNumber(context){
context.commit('increment')
}
}
复制代码
Action 函数接受一个与 store 实例具备相同方法和属性的 context 对象,所以你能够调用 context.commit 提交一个 mutation,或者经过 context.state 和 context.getters 来获取 state 和 getters
addNumber( {commit} ){
commit('increment')
}
以上这种写法等同于:
addNumber(context){
context.commit('increment')
}
复制代码
Action 经过 store.dispatch 方法触发:
this.$store.dispatch('addNumber')
复制代码
同mutation 同样你也能够在action的时候传递参数
const mutations = {
increment(state, number) {
state.number += number
}
}
const actions = {
addNumber(context, number){
context.commit('increment', number)
}
或者:
addNumber( {commit}, number){
commit('increment', number)
}
}
触发方法: this.$store.dispatch('addNumber', 10)
复制代码
关于在action 处理异步操做能够看下面这个例子:
const actions = {
getData({commit}) {
return new Promise((resolve, reject)=> {
setTimeout(()=>{
commit('getList')
resolve()
}, 1000)
})
}
}
复制代码
而后再
this.$store.dispatch('getData').then(() => {
// ...
})
复制代码
import Vue from "vue";
import Vuex from "vuex";
import { resolve, reject } from "any-promise";
Vue.use(Vuex);
const state = {
number: 1,
list: [1, 2, 3, 4, 5]
}
const getters = {
getNumber(state) {
return state.number + 1 // 2
},
getDoubNumber(state, getters) {
return state.number + getters.getNumber // 3
},
filterNumber:(state)=>(num)=> {
return state.list.find(item=> item%num === 0)
}
}
const mutations = {
increment(state, n) {
state.number += n
},
getList(state) {
state.list = state.list.forEach((item)=> item*2)
}
}
const actions = {
addNumber( {commit} , n){
commit('increment', n)
},
getData({commit}) {
return new Promise((resolve, reject)=> {
setTimeout(()=>{
commit('getList')
resolve()
}, 1000)
})
}
}
export default new Vuex.Store({
state,
getters,
mutations,
actions
});
复制代码
要用 首先得引入:
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex';
复制代码
这玩意儿其实就是Vuex 内置的辅助函数,方便咱们获取store里面的数据和方法
computed: {
...mapState([
'number'
])
}
复制代码
// 使用对象展开运算符将 getter 混入 computed 对象中
computed: {
...mapGetters([
'getNumber',
'getDoubNumber',
// ...
])
}
复制代码
methods: {
...mapMutations([
'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
...mapMutations({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
})
}
复制代码
methods: {
...mapActions([
'addNumber', // 将 `this.addNumber()` 映射为 `this.$store.dispatch('addNumber')`
// `mapActions` 也支持载荷:
'addNumber' // 将 `this.addNumber(amount)` 映射为 `this.$store.dispatch('addNumber', amount)`
]),
...mapActions({
requestData: 'getData' // 将 `this.requestData()` 映射为 `this.$store.dispatch('getData')`
})
}
复制代码
以上是对Vuex实现状态管理的一个整个过程的理解,参考官方文档,而后本身写一遍,比较容易明白其中的道理,后面有时间想写React里面关于Redux实现状态管理的一个过程,对比其中,其实他们思想差很少, 只不过redux实现过程更多点,敬请期待!