Vuex
Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式。它採用集中式儲存管理應用的所有元件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化
安裝 Vuex
1、npm install vuex --save
2、建立store
物件,src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {};
const getters = {};
const mutations = {};
const actions = {};
const store = new Vuex.Store({
state,
getters,
mutations,
actions,
});
export default store;
3、在入口檔案src/main.js
引入並注入store
import Vue from 'vue'
import store from './store'
new Vue({
el:'#app',
store,
})
Vuex選項
1、state
- 定義
state
const state = {
user:null,
}
- 在元件中獲取
state
,由於 Vuex 的狀態儲存是響應式的,從 store 例項中讀取狀態最簡單的方法就是在計算屬性中返回某個狀態
export default {
computed:{
user:this.$store.state.user,
}
}
mapState 輔助函式幫助我們生成計算屬性
import {mapState} from 'vuex'
export default {
computed:{
localComputed(){
},
//此處是陣列的形式,當然也可以使用物件的方式
...mapState([
'user'
]),
}
}
2、getters
- 定義**getters
Vuex 允許我們在 store 中定義“getter”(可以認為是 store 的計算屬性)。就像計算屬性一樣,getter 的返回值會根據它的依賴被快取起來,且只有當它的依賴值發生了改變才會被重新計算
getter 方法接受以下引數:state,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)
},
getTodoById: (state) => (id) => { //返回一個函式,實現給 getter 傳參
return state.todos.find(todo => todo.id === id)
},
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
})
- 在元件中獲取getters
export default {
computed: {
doneTodosCount () {
return this.$store.getters.doneTodosCount
}
}
}
同樣的,可以使用mapGetters
輔助函式
import mapGetters from 'vuex'
export default {
computed:{
localComputed(){
},
//此處是陣列的形式,當然也可以使用物件的方式
...mapGetters([
'doneTodosCount'
]),
}
}
3、mutations
更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation
一條重要的原則就是要記住 mutation 必須是同步函式
在 store 上註冊 mutation,處理函式總是接受 state 作為第一個引數(如果定義在模組中,則為模組的區域性狀態),payload 作為第二個引數(可選),可以是一個變數,或者是一個物件
- 定義
mutations
const mutations = {
increment (state, n) {
state.count += n
},
}
- 在元件中提交 Mutation
你可以在元件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 輔助函式將元件中的 methods 對映為 store.commit 呼叫(需要在根節點注入 store)
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapMutations([
'increment', // 將 `this.increment()` 對映為 `this.$store.commit('increment')`
// `mapMutations` 也支援載荷:
'incrementBy' // 將 `this.incrementBy(amount)` 對映為 `this.$store.commit('incrementBy', amount)`
]),
...mapMutations({
add: 'increment' // 將 `this.add()` 對映為 `this.$store.commit('increment')`
})
}
}
4、actions
Action 提交的是 mutation,而不是直接變更狀態
Action 可以包含任意非同步操作
在 store 上註冊 action。處理函式總是接受 context 作為第一個引數,payload 作為第二個引數(可選)
context 物件包含以下屬性:
{
state, // 等同於 `store.state`,若在模組中則為區域性狀態
rootState, // 等同於 `store.state`,只存在於模組中
commit, // 等同於 `store.commit`
dispatch, // 等同於 `store.dispatch`
getters, // 等同於 `store.getters`
rootGetters // 等同於 `store.getters`,只存在於模組中
}
- 定義
actions
const actions = {
increment({commit},amount){
commit('increment',amount)
},
}
- 在元件內分發
actions
import {mapActions} from 'vuex'
export default {
methods:{
...mapActions([
'increment', // 將 `this.increment()` 對映為 `this.$store.dispatch('increment')`
// `mapActions` 也支援載荷:
'incrementBy' // 將 `this.incrementBy(amount)` 對映為 `this.$store.dispatch('incrementBy', amount)`
]),
...mapActions({
add: 'increment' // 將 `this.add()` 對映為 `this.$store.dispatch('increment')`
})
}
}
另外:
1、應用層級的狀態應該集中到單個 store 物件中
2、提交 mutation 是更改狀態的唯一方法,並且這個過程是同步的
3、非同步邏輯都應該封裝到 action 裡面
4、如果 store 檔案太大,只需將 action、mutation 和 getter 分割到單獨的檔案
本作品採用《CC 協議》,轉載必須註明作者和本文連結