1. 程式人生 > 實用技巧 >vue mutations與actions的區別

vue mutations與actions的區別

關於mutations與actions的區別,網上有很多文章,大多是照著vue.js的教程再來一波!!因為最近接手vue專案,自己之前vue的知識點掌握也不深,就此機會把這個知識點再深挖一下。

使用vuex進行狀態管理時,使用mutations來進行state的狀態變更。其中一個要求就是mutations中的程式碼必需時同步的,因此要想在其中包含非同步操作是不合適的。如下程式碼:

const app = {
    state: {
        //直接訪問state中的元素,可獲得元素的值,但是不利於封裝
        //並且在訪問是如果store.count的訪問方式也不方便
        //
mapStore方便快速將store.count對映到計算屬性,但本質上還是直接訪問元素的值,無法達到getters封裝取值時二次加工的效果 count: 100 }, getters: { //對state元素進行取值進行封裝,可以方便實現在取值時的各種運算需求 //mapGetters與mapState型別,實現快速將getters對映到計算屬性 getCount: state => { return state.count > 100 ? true : false } }, mutations: {
//對state元素值的寫入進行封裝,可以方便實現在賦值時的各種運算需求 //mapMutations與mapState型別,實現快速將mutations對映到方法中methods add(state, n) { state.count += n } } } export default app

如上面的add中要根據n的奇偶性來非同步request不同外部介面獲取資料用於運算,此時mutation中就導致無法完成操作。因此在沒有actions的概念下,我們只能將(根據n的奇偶性來非同步request不同外部介面獲取資料)其提前與add執行,然後將執行結果傳給add來實現該目的。但這麼做的結果是邏輯被拆開,邏輯鬆散化了。個人認為這就是mutations的短板,為了能將該短板補上,actions就橫空出世了。

action中則可以按上面的邏輯執行,並最終提交的mutationadd,瞬間海闊天空了!

//基礎store配置資訊
import Vue from 'vue'

const app = {
    state: {
        //直接訪問state中的元素,可獲得元素的值,但是不利於封裝
        //並且在訪問是如果store.count的訪問方式也不方便
        //mapStore方便快速將store.count對映到計算屬性,但本質上還是直接訪問元素的值,無法達到getters封裝取值時二次加工的效果
        count: 100
    },
    getters: {
        //對state元素進行取值進行封裝,可以方便實現在取值時的各種運算需求
        //mapGetters與mapState型別,實現快速將getters對映到計算屬性
        getCount: state => {
            return state.count > 100 ? true : false
        }
    },
    mutations: {
        //對state元素值的寫入進行封裝,可以方便實現在賦值時的各種運算需求
        //mapMutations與mapState型別,實現快速將mutations對映到方法中methods
        add(state, n) {
            state.count += n
        }
    },
    actions:{
        aadd({commit},n){
            if(n%2){
                Vue.axios.get('http://127.0.0.1:8881/home/a').then(res=>{
                    console.log(res.data)
                    commit('add',res.data)
                })
            }
            else{
                Vue.axios.post('http://127.0.0.1:8881/home/b').then(res=>{
                    console.log(res.data)
                    commit('add',res.data)
                })
            }
        }
    }
}
export default app

這個就能在actions中順利的執行ajax非同步操作了,nice!

完整程式碼:

//main.js
import Vue from 'vue'
import App from './App.vue'
import Vuex from 'vuex'
import axios from 'axios'
import VueAxios from 'vue-axios'
import storeSetting from './strore'

Vue.use(Vuex)
Vue.use(VueAxios, axios)

const store = new Vuex.Store(storeSetting)

new Vue({
  store,
  render: h => h(App),
}).$mount('#app')
// /store/index.js,基礎store配置資訊
//引入vue,方便呼叫axios
import Vue from 'vue'

const app = {
    state: {
        count: 100
    },
    getters: {
        getCount: state => {
            return state.count > 100 ? true : false
        }
    },
    mutations: {
        add(state, n) {
            state.count += n
        }
    },
    actions:{
        aadd({commit},n){
            if(n%2){
                Vue.axios.get('http://127.0.0.1:8881/home/a').then(res=>{
                    console.log(res.data)
                    commit('add',res.data)
                })
            }
            else{
                Vue.axios.post('http://127.0.0.1:8881/home/b').then(res=>{
                    console.log(res.data)
                    commit('add',res.data)
                })
            }
        }
    }
}
export default app
<template>
  <div id="app">
    <p><button @click="add">count</button></p>
  </div>
</template>

<script>
import setting from "./components/routes/nameview/Setting.vue";
import { mapState } from "vuex";

export default {
  components: { setting },
  name: "App",
  methods: {
    add(){
      this.$store.dispatch('aadd',2)
    }
  }
};
</script>