vue mutations與actions的區別
阿新 • • 發佈:2020-12-06
關於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>