vuex學習總結

state

  • 做用:至關於vue中的data,用於存儲狀態,是惟一數據源,並且是隻讀,不能作直接修改。
  • 語法:
const store = new Vuex.Store({
  state: {
    text:'hello world'
  }
})
  • 調用:
// 方法1
store.state.text
// 方法2(須要使用vue.use注入)
this.$store.state.text
// 方法3,經過輔助函數mapState
import { mapState } from 'vuex';
export default {
    computed: {
        // 使用ES6的擴展運算符來達到將state釋放出來
        ...mapState([
          // 映射 this.text 爲 store.state.text
          'text'
        ])
    }
}

注意:若是通常state初始化時最好就設置好所需屬性,若是真的須要動態需改某一個屬性,能夠以下:
1)Vue.set(obj, 'newProp', 123)
2)state.obj = { ...state.obj, newProp: 123 }vue

getter

  • 做用:至關於vue中的computed,做用也是相似的。
  • 語法:
const store = new Vuex.Store({
  state: {
    text:'hello world'
  },
  getters: {
    // 第一個參數固定是state對象,第二個參數固定是getters對象
    getText: (state, getters) => {
        return state.text + ' xiaoming';
    },
    // getters方法中調用getters方法
    getGettersText: (state, getters) => {
        return getters.getText;
    },
    // getters方法返回一個函數
    getFuncText: (state,getters) => (name) => {
        return state.text + ' ' + name;
    }
  }
})
  • 調用:
// 方法1
store.getters.getText
// 方法2
this.$store.getters.getText
// 方法3,經過輔助函數mapGetters
import { mapGetters } from 'vuex'
export default {
    computed: {
        ...mapGetters([
            'getText',
            'getGettersText',
            'getFuncText'
        ])
    }
}

mutation

  • 做用:至關於vue中data對象的的set方法,是惟一能夠改變state數據的方式,定位是同步改變,即在mutation的方法中不支持異步邏輯,這個的具體緣由是由於mutation相似於事件監聽的回調函數,而任何在回調函數中進行的狀態的改變都是不可追蹤的。
  • 語法:
const store = new Vuex.Store({
  state: {
    text:'hello world'
  },
  mutations: {
    // 第一個參數固定是state,剩下還能夠再傳入一個或0個參數(也叫載荷),這個載荷參數通常是對象,方便傳入多個值
    changeText (state, payload) {
      // 變動狀態
      state.text = 'welcome' + payload.name;
    }
  }
})
  • 調用:
// 方法1,只是第二個參數是載荷
store.commit('changeText', {
    name: 'xiaoye'
})
// 方法2,至關於整個對象都是載荷
store.commit({
    type: 'changeText',
    name: 'xiaoye'
})
// 方法3
this.$store.commit('changeText', {
    name: 'xiaoye'
})

// 方法4,依賴輔助函數mapMutations 
import { mapMutations } from 'vuex';
export default {
  methods: {
  // 將this.changeText({name: 'xiaoye'})映射爲this.$store.commit('changeText', {name: 'xiaoye'});
    ...mapMutations([
      'changeText'
    })
  }
}

action

  • 做用:至關於vue中的method,不能直接修改state,只能經過調用mutation中的方法間接改變state,定位是異步改變,固然也能夠同步,若是是須要異步改變的邏輯建議寫在action中,其實用過action就知道,其實就至關於把原本屬於vue中的method中的方法放到vuex中的action中來而已,只是說公共的異步請求再也不用寫那麼多份在不一樣的method中,只須要寫一份放在action中便可。
  • 語法:
const store = new Vuex.Store({
  state: {
    text:'hello world'
  },
  mutations: {
    // 第一個參數固定是state,剩下還能夠再傳入一個或0個參數(也叫載荷),這個載荷參數通常是對象,方便傳入多個值
    changeText (state, payload) {
      // 變動狀態
      state.text = 'welcome' + payload.name;
    }
  },
  actions: {
    // 第一個參數是固定的一個相似store的實例,具備和store實例相同方法和屬性,便可以直接調用state,getters,commit,dispatch等;第二個參數同mutations同樣,是載荷
    asynChangeText (context, payload) {
        setTimeout(() => {
          context.commit('changeText', payload.asynName)
        }, 1000)
    }
  }
})
  • 調用:
// 方法1
store.dispatch('asynChangeText', {
  asynName: 'xiaoMing'
})

// 方法2
store.dispatch({
  type: 'asynChangeText',
  asynName: 'xiaoMing'
})

// 方法3
this.$store.commit('asynChangeText', {
    asynName: 'xiaoMing'
})

// 方法4,依賴輔助函數mapActions
import { mapActions } from 'vuex';
export default {
  // 用法同 mutation 同樣
  methods: {
    ...mapActions([
      'asynChangeText'
    })
  }
}

module

  • 做用:將state模塊化和嵌套子模塊化,避免state過大,而變得臃腫,不方便管理,每個模塊都包含完整的state、actions、mutations、getters。
  • 語法1(默認命名空間):
/**
 ** 模塊化(默認命名空間)
 */
const moduleA = {
  state: {
    a: 1,
  },
  mutations: {
    // 該state包含的是本模塊本身以及子模塊的state
    setA (state, payload) {}
  },
  actions: {
    // 該context除包含本模塊本身以及子模塊的屬性和方法外,還另外多包含rootGetters和rootState兩個屬性根模塊(moduleA)的state和getter
     getAsynA (context, payload) {}
  },
  getters: {
    // 這裏的rootState和rootGetter等同於根模塊(moduleA)的state和getter
    getA (state, getters, rootState, rootGetter) {}
  },
  // 兩個子模塊
  modules: {
    moduleB,
    moduleC
  }
}

// 和moduleA模塊同樣,只是rootState和rootGetter依然表示moduleA這個跟模塊而已
const moduleB = {
  state: {  },
  mutations: { ... },
  actions: { ... }
}
// 同moduleB
const moduleC = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store(moduleA)

注意:在默認的命名空間中:
1)全部的模塊和子模塊的mutations和actions都是包含在全局中的,也叫在全局命名空間中。也就是說若是不一樣的模塊中有相同的actions或者mutations是會存在重複註冊掛載到全局中的狀況的,只不過他們不是覆蓋而是追加的關係而已,被調用的順訊也是按照模塊的註冊順序遞歸調用的。vuex

2)全部模塊和子模塊的getters都是包含在全局中的,不過不一樣的是若是出現不一樣模塊之間重名的狀況,不是追加而是先到先得,即哪個模塊先註冊,即便用誰的。異步

3)而state是仍然是劃分模塊的,外部若是要調用,調用方式也是按照模塊的層級路徑來調用的。即:moduleA的狀態:store.state;moduleB的狀態:store.state.moduleB模塊化

  • 調用:
// 調用state,方法1
store.state.a
store.state.moduleB.b
// 調用state,方法2
this.$store.state.a
this.$store.state.moduleB.b
// 調用state,方法3
import {mapState} from 'vuex';
export default {
    computed: {
        ...mapState([
            'a',        // 是moduleA的state
            'moduleB',   // moduleB是一個對象,包含本身以及子模塊的state
            'c': state => state.a.moduleC.c // moduleC模塊下的state能夠經過這種方法的形式返回值
        ])
    }
}

// 調用getter,方法1
store.getters.getA
store.getters.getB
// 調用getter,方法2
this.$store.getters.getA
this.$store.getters.getB
// 調用getter,方法3
import { mapGetters } from 'vuex'
export default {
    computed: {
        ...mapGetters([
            'getA',
            'getB'
        ])
    }
}

// 調用mutations,方法1,和getter相同點都是掛載在全局中,不一樣點是不一樣模塊中存在相同名稱是會按順序觸發的
store.commit('setA')
store.commit('setB')
// 調用mutations,方法2
store.commit({
    type: 'setA'
})
// 調用mutations,方法3
this.$store.commit('setA')
// 調用mutations,方法4
import { mapMutations } from 'vuex';
export default {
  methods: {
    ...mapMutations([
      'setA'
    })
  }
}

// 調用actions,同mutations同樣
  • 語法2(命名空間):
/**
 ** 模塊化(命名空間)
 */
const moduleA = {
  namespaced: true,
  state: {
    a: 1,
  },
  mutations: {
    // 該state包含的是本模塊本身以及子模塊的state
    setA (state, payload) {}
  },
  actions: {
    // 該context除包含本模塊本身以及子模塊的屬性和方法外,還另外多包含rootGetters和rootState兩個屬性根模塊(moduleA)的state和getter
     getAsynA (context, payload) {}
  },
  getters: {
    // 這裏的rootState和rootGetter等同於根模塊(moduleA)的state和getter
    getA (state, getters, rootState, rootGetter) {}
  },
  // 兩個子模塊
  modules: {
    moduleB,
    moduleC
  }
}

// 和moduleA模塊同樣,只是rootState和rootGetter依然表示moduleA這個跟模塊而已
const moduleB = {
  //  namespaced: true, // 這裏若是不設置命名空間的話那moduleC就繼承父命名空間
  state: {  },
  mutations: { ... },
  actions: { ... }
}
// 同moduleB
const moduleC = {
  namespaced: true,
  state: { ... },
  mutations: { ... },
  actions: { ... },
  modules: {
        moduleD: {
            namespaced: true,
            state: {
                d: 1,
            },
            mutations: {},
            actions: {}
        }
    }
}

const store = new Vuex.Store(moduleA)

注意:在命名空間中:
1)全部的模塊和子模塊的mutations、actions、getters都是包含在各自的命名空間或父命名空間中,即自動根據模塊註冊的路徑調整命名函數

2)而state不受影響,由於默認state也已是層級嵌套的了。this

  • 調用
// 調用state,方法4(前三個方法和默認命名空間相似)
computed: {
  ...mapState('moduleC/moduleD', {
    d: state => state.d
  }),
  ...mapState('moduleC/moduleD', ['d']) // 這兩種是同樣的,只是寫法不一樣
},
// 調用state,方法5(經過輔助函數createNamespacedHelpers)
import { createNamespacedHelpers } from 'vuex';
const { mapState } = createNamespacedHelpers('moduleC/moduleD');
export default {
  computed: {
    // 在 `moduleC/moduleD` 中查找
    ...mapState({
      d: state => state.d
    })
  }
}

// 其餘的getter、mutations、actions也是和state相似的以上的方法

plugins

  • 做用:plugins 是vuex中的一個函數,通常配合 subscribe 函數實現相似於攔截器的效果,並且是一個成功以後的攔截器,是每次 mutation 調用成功以後的鉤子,它接收store 實例做爲做爲惟一的參數。
  • 語法:
const myPlugin = store => {
    // mutation 的格式爲:{ type, payload },經過這個對象能夠判斷是哪個 mutation 被調用了,額外的參數是什麼。
    store.subscribe((mutation, state) => {
        if (mutation.type === 'updateA') {
            console.log(mutation)
            console.log(state)
        }
    })
}
const moduleA = {
    state: {
        a: 1,
    },
    mutations: {
        // 被調用完成以後會觸發 myPlugin 中的 subscribe 回調
        updateA (context, payload) {
            console.log('A')
        }
    },
    actions: {...},
    getters: {...},
    modules: {...},
    plugins: [myPlugin]
}

export default new Vuex.Store(moduleA);

注意:在插件中若是要修改state狀態,也須要經過store調用commit,從而觸發 mutation 改變state的狀態,也就是說不能直接修改state狀態。spa

strict

  • 上面一直強調就是修改只能在 mutations 中完成,爲了強制約束,但是在vuex實例化的時候傳入該屬性(嚴格模式)。
  • 語法
const moduleA = {
    state: {...},
    mutations: {...},
    actions: {...},
    getters: {...},
    modules: {...},
    plugins: [...],
    strict: true
}

export default new Vuex.Store(moduleA);
相關文章
相關標籤/搜索