Vuex

安裝配置

npm install vuex --save

我使用的vue-cli腳手架(不再強調),在main.js中引入並且配置到全局

import Vuex from 'vuex';
import storeConfig from './config/store.js';
Vue.use(Vuex);
const store = new Vuex.Store(storeConfig);
new Vue({
  store,
  render: h => h(App)
}).$mount('#app');

核心概念

那麼我就看一下store.js有哪些內容吧:

const storeConfig = {
    state: {
        data: [],
    },
};
export default storeConfig;
1. state

就是全局數據,在所有組件中都可以獲取到。這個沒什麼多說的。
在組件中如果要獲取store中的state,可以通過兩種方法:首先第一就是直接訪問

this.$store.state.data

可以看出,如果某個子組件中要多次使用store中的數據,那麼這樣寫起來會很囉嗦的,我們可以使用mapState輔助函數來減少敲鍵盤的次數。

該函數返回一個對象,如果映射的計算屬性名稱和state中的名稱相同,可以直接傳入一個數組。

import { mapState } from 'vuex'
export default {
    computed: {
        ...mapState(['data',])
    }
}

如果要對屬性進行重命名,可以傳入一個對象。使用的時候直接使用心得名稱即可。

...mapState({
    myData: 'data'
})
2. getters

有時我們需要獲取state中的數據進行處理之後的數據,比如篩選之類的。並且這個處理之後的數據要在多個組件中使用,每個組件都寫處理方法肯定不是我們想要的,這時getter就很有用了。

const storeConfig = {
    state: {
        data: [],
    },
    getters: {
        getList: (state, getters) => {
          return state.data.filter(item=> item.id !== 0)
        }
    }
};

這樣就可以直接從getters中獲取處理過的數據,而且這個值是會被緩存的,如果計算的依賴不變化是不會重新計算的,減少了不必要的消耗。第二個參數表示getter也接受其他getter。

在組件中要獲取getter也是非常簡單的,有以下三種方法:
第一種,直接通過Getter暴露的對象訪問,

this.$store.getters.getList

第二種,如果getter的返回值是一個函數,我們可以通過調用方法的形式訪問,

getters: {
  getTodoById: (state) => (id) => {
    return state.todos.find(todo => todo.id === id)
  }
}

this.$store.getters.getTodoById(5)

第三種,通過輔助函數mapGetters訪問,使用方法和mapState基本一致,可以接受一個數組,也可以接受一個對象來重命名。

import { mapGetters } from 'vuex'
export default {
    computed: {
        ...mapGetters(['getList',])
    }
}
3. mutations

state中的數據是不能隨便修改的,只能通過提交mutation修改,

const storeConfig = {
    state: {
        count: 1
    },
    mutations: {
        increment (state, n) {
          state.count = state.count + n;
        }
    }
};

提交時可以通過commit方法來提交,接受第二個參數作爲要傳給mutation的參數。這個參數可以是一個單一的值,大多數情況下我們需要的是一個對象。

this.$store.commit("increment", 10);

也可以通過mapMutations輔助函數提交,合併到methods中,直接當方法調用即可。

import { mapMutations } from "vuex";
export default{
    methods: {
        ...mapMutations(['increment '])
    },
    mounted(){
        this.increment({num: 10});
    }
}

補充:

  1. 使用常量代替mutation事件類型。這樣我們可以把所有的mutation提取到一個文件中單獨管理

mutationTypes.js

export const CHANGEDATA= 'CHANGEDATA'
import { CHANGEDATA} from 'mutationTypes.js'
//...
mutations:{
    [CHANGEDATA](state){
        ...
    } 
}
// ...
  1. mutation必須是同步的,如果要想異步調用請看下面的actions
4. actions

actions其實就是給提交mutation添加了一箇中間環節,通過先分發Action,然後再action中提交mutation。重要的是action中沒有同步的限制。

這裏直接複製官網的一段代碼,懶得敲了,

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})

action函數接受一個context參數,這個參數和store實例一樣,因此可以調用context.commit,也可以通過它調用state或者getters等等。

我們可以使用ES6的參數結構來簡化代碼。

actions: {
  increment ({ commit }) {
    commit('increment')
  }
}

接下來怎麼分發action呢?同樣的,可以直接調用dispatch方法分發,

this.$store.dispatch("increment");

也可以使用輔助函數mapActions來分發。使用方法和之前的輔助函數都一樣,不廢話了。

import { mapActions } from 'vuex'
export default {
  methods: {
    ...mapActions(['increment']),
    ...mapActions({
      add: 'increment' // 將 `this.add()` 映射爲 `this.$store.dispatch('increment')`
    })
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章