更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。我們接着上一章的例子,我們想增加明星的名字,應該這樣做:
在store的mutations裏添加addStar方法
mutations: {
addStar(state){
state.stars.push({name:'李連杰',sex:'男'})
}
},
在A組件裏通過this.$store.commit('addStar')來提交mutation,具體代碼如下:
<template>
<div id="A">
<p>A組件</p>
<p>全部明星</p>
<p v-for="star in stars" :key="star.name">
{{ star.name }}---{{ star.sex }}
</p>
<button @click="addStar" style="color:black">添加明星</button>
</div>
</template>
<script>
import { mapState } from "vuex";
export default {
name: "A",
computed: mapState(["stars"]),
methods:{
addStar(){
this.$store.commit('addStar');
}
}
};
</script>
<style scoped>
#A {
width: 60%;
background-color: lightgreen;
color: white;
}
</style>
這樣,我們在點擊按鈕時就添加上了明星,不過這個添加的明星不是由組件提供的,我們可以通過傳入一個對象來實現。
在A組件中,我們使用input組件來讓用戶輸入明星的名字和性別,然後通過提交mutation來傳
<template>
<div id="A">
<p>A組件</p>
<p>全部明星</p>
<p v-for="star in stars" :key="star.name">
{{ star.name }}---{{ star.sex }}
</p>
添加明星的名字:<a-input v-model="name" type="text" style="color:black;" />
添加明星的性別:<a-input v-model="sex" type="text" style="color:black;" />
<a-button @click="addStar" style="color:black" type="primary">
添加明星
</a-button>
</div>
</template>
<script>
import { mapState } from "vuex";
export default {
name: "A",
data() {
return {
name: "",
sex: ""
};
},
computed: mapState(["stars"]),
methods: {
addStar() {
let that = this;
this.$store.commit("addStar", {
name: that.name,
sex: that.sex
});
}
}
};
</script>
<style scoped>
#A {
width: 60%;
background-color: lightgreen;
color: white;
}
</style>
然後修改store/index.js裏的addStar方法
addStar(state, star) {
state.stars.push(star);
}
最後效果如下:
注意,mutation是同步調用,要實現異步操作,就要使用action
2 Action操作
有些狀態要與數據庫交互後才能進行修改,這時就要進行異步操作,我們前端進行Action操作,Action層請求後臺後在提交mutation進行狀態修改,實現訪問後臺與本地狀態修改的解耦
我們現在就模擬這種異步操作,首先A組件添加addStar2方法,addStarAction是Action裏的方法
addStar2() {
let that = this;
this.$store.dispatch("addStarAction", {
name: that.name,
sex: that.sex
});
}
然後store/index.js裏的Action裏添加,這裏的context是state的副本
addStarAction(context, star) {
console.log("Action");
return new Promise((resolve) => {
setTimeout(() => {
context.commit("addStar", star);
resolve();
}, 1000);
});
}
由於我們只使用commit方法,因此也可使用{commit},最後如下
addStarAction({ commit }, star) {
console.log("Action");
return new Promise((resolve) => {
setTimeout(() => {
commit("addStar", star);
resolve();
}, 1000);
});
}
這樣就模擬了異步操作,1秒後數據被添加上。
可以這樣理解mutation和action:state類似數據庫,mutation類似java中的dao,與數據庫進行直接交互,而action類似java中的service層,用來調用dao。