vue 狀態管理(二)

上篇文章中說了 state 和 getters,本篇文章就來講說 mutations 和 actions。 提交 mutations 是改變 state 的惟一方式,不能用異步操做。actions 經過分發 action 來提交 mutation,可包含異步操做,好比 xhr 。javascript

mutations

聲明 mutations:html

// mutations.js
import vue from 'vue'
export default {
	CHANGE_LAST_NAME(state, newLastName) {
		state.lastName = newLastName
	},
	CHANGE_AGE(state, params) {
		state.age = params.age + 5
	},
	// 新增一個屬性
	SET_REPOS(state,repos){
		// 給 state 新添加屬性
		vue.set(state,'repoList',repos)
	}
}
複製代碼

使用 mutationsvue

  1. 經過 mapMutations 映射方法;
  2. 在方法中 調用 this.$store.commit('mutaion')
  3. 能夠在 mutation 種給 state 新增狀態(屬性),新增的狀態會響應到視圖上。
<template>
	<div class="store">
		<p>基本信息:{{this.info}}</p>
		<input type="text" name="age" id="age" v-model="age" placeholder="請輸入年紀" />
		<button @click="changeAge">修改年紀</button>
		<button @click="changeAge2">修改年紀2</button>
		<p>年紀:{{this.$store.state.age}}</p>
		<input type="text" v-model="lastName" placeholder="請輸入姓氏" @input="changeLastName" />
	</div>
</template>
<script> import CustomInput from '_c/CustomInput.vue' import { mapState, mapGetters, mapMutations } from 'vuex' export default { name: 'Store', data() { return { age: '', lastName: "" } }, methods: { handleInput(val) { this.value = val }, //方法名和 muations 相同 ...mapMutations(['CHANGE_LAST_NAME', 'CHANGE_AGE']), // 將 `this.changeAge2()` 映射爲 `this.$store.commit('CHANGE_AGE')` ...mapMutations({ changeAgeAlias: 'CHANGE_AGE' }), changeAge() { // 傳遞載荷 // this.$store.commit('CHANGE_AGE', { age: Number.parseInt(this.age) }) //對象提交方式 // this.$store.commit({ type: 'CHANGE_AGE', age: Number.parseInt(this.age) }) this.CHANGE_AGE({ age: Number.parseInt(this.age) }) }, changeAge2() { this.changeAgeAlias({ age: Number.parseInt(this.age) }) }, changeLastName() { // this.$store.commit('CHANGE_LAST_NAME', this.lastName) this.CHANGE_LAST_NAME(this.lastName) }, } } </script>
複製代碼

actions

mutation 只能是同步操做,爲了使用異步操做,Vuex 提供了 actions。java

  • Action 提交的是 mutation,而不是直接變動狀態。
  • Action 能夠包含任意異步操做。

聲明 actionsios

  • action 接收一個和 store 具備相同屬性和方法的對象,可 context.commit 提交 mutation;
  • 能夠解構賦值,獲取 commitdispatch,commit 用於提交 mutation, dispatch 用於分發其餘 action。
import http from 'axios'
export default {
	// action 接收一個和 store 具備相同屬性和方法的對象,可 context.commit 提交 mutation
	changeAgeAsync(context, params) {
		console.dir(context)
		//模擬異步操做
		setTimeout(() => { context.commit('CHANGE_AGE', params) }, 5000)
	},
	//經過 github API 獲取個人 github 倉庫信息
	async 	repos({ commit, dispatch }, username) {
		let response = await http.get(`https://api.github.com/users/${username}/repos`)
		let repoList = response.data
		commit('SET_REPOS', repoList)
		// 分發其餘 action 造成組合 action
		dispatch('changeAgeAsync', { age: 30 })
		// 給 state 新添加屬性 不能直接改變 state
		// vue.set(state,'repoList',repoList)
	}
}
複製代碼

在組件中使用 actionsgit

  • 經過 mapActions 映射爲方法。
  • this.$store.dispatch
<template>
	<div class="store">
		<input type="text" name="age" id="age" v-model="age" placeholder="請輸入年紀" />
		<button @click="changeAge">修改年紀</button>
		<p>年紀:{{this.$store.state.age}}</p>
		<input type="text" v-model="lastName" placeholder="請輸入姓氏" @input="changeLastName" />
		<hr>
		<button @click="getRepos">獲取倉庫列表</button>
		<h2>個人倉庫列表:</h2>
		<ol>
			<li v-for="(item, index) in repoList" :key="index">{{item.full_name}}</li>
		</ol>
	</div>
</template>
<script> import { mapState, mapActions} from 'vuex' export default { name: 'Store', data() { return { age: '', lastName: "" } }, methods: { ...mapActions(['changeAgeAsync','repos']), changeAge() { // this.$store.dispatch('changeAgeAsync',{ age: Number.parseInt(this.age) }) this.changeAgeAsync({age: Number.parseInt(this.age)}) }, getRepos(){ // this.$store.dispatch('repos','jackzhoumine') this.repos('jackzhoumine') } }, computed: { //計算屬性名和 state 屬性名相同:傳入數組 ...mapState(['repoList']) } } </script>
複製代碼

module

狀態對象很複雜時用 module 劃分。 這個彷佛用得不多。須要用時看veux 文檔便可。github

總結

  1. 提交 mutation 是改變你 state 的惟一方式;
  2. 方法執行上:
    • dispatch 分發 action ;
    • commit 提交mutation。
  3. 輔助方法的映射
  • getters、state 映射爲計算屬性;
  • actions、mutations 映射爲法法。
  1. 分離功能:
  • state 保存數據;
  • getters 是對 state 的操做;
  • actions 要提交 mutation;
  • mutations 改變 state。
  1. 異步與同步:
  • action 封裝異步處理;
  • mutation 只能是同步。
  1. 視圖響應

( vue component dispatch → ) vue component commitstate → ( getters →) vue componentvuex

  1. state 對象太過複雜,使用 module 劃分。

參考

相關文章
相關標籤/搜索