天天看點

Vue入門029- 求和案例_vuex版(Vuex子產品化編碼,啟用命名空間)

作者:CShap新勢力

看項目結構

Vue入門029- 求和案例_vuex版(Vuex子產品化編碼,啟用命名空間)

項目結構

原來store隻有一個index.js檔案

所有的邏輯都是寫在index.js檔案中的。這樣不利于維護,是以要按元件拆開來寫

分出3個檔案

index.js 這個是總檔案,主要用來組織下面2個檔案,并且建立store對象用的

count.js 對應 Count.vue 元件

person.js 對應 Person.vue 元件

store/index.js

//該檔案用于建立Vuex中最為核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
import countOptions from './count'
import personOptions from './person'
//應用Vuex插件
Vue.use(Vuex)

//建立并暴露store
export default new Vuex.Store({
	modules:{
		countAbout:countOptions,
		personAbout:personOptions
	}
})           

代碼解釋:

import countOptions from './count'  //引用count.js
import personOptions from './person' //引用person.js           
//建立并暴露store
export default new Vuex.Store({
	modules:{
		countAbout:countOptions,  //子產品化
		personAbout:personOptions
	}
})           

store/count.js

//求和相關的配置
export default {
	namespaced:true, //啟用命名空間
	actions:{
		jiaOdd(context,value){
			console.log('actions中的jiaOdd被調用了')
			if(context.state.sum % 2){
				context.commit('JIA',value)
			}
		},
		jiaWait(context,value){
			console.log('actions中的jiaWait被調用了')
			setTimeout(()=>{
				context.commit('JIA',value)
			},500)
		}
	},
	mutations:{
		JIA(state,value){
			console.log('mutations中的JIA被調用了')
			state.sum += value
		},
		JIAN(state,value){
			console.log('mutations中的JIAN被調用了')
			state.sum -= value
		},
	},
	state:{
		sum:0, //目前的和
		school:'尚矽谷',
		subject:'前端',
	},
	getters:{
		bigSum(state){
			return state.sum*10
		}
	},
}           

store/person.js

//人員管理相關的配置
import axios from 'axios'
import { nanoid } from 'nanoid'
export default {
	namespaced:true, //啟用命名空間
	actions:{
		addPersonWang(context,value){
			if(value.name.indexOf('王') === 0){
				context.commit('ADD_PERSON',value)
			}else{
				alert('添加的人必須姓王!')
			}
		},
		addPersonServer(context){
			axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then(
				response => {
					context.commit('ADD_PERSON',{id:nanoid(),name:response.data})
				},
				error => {
					alert(error.message)
				}
			)
		}
	},
	mutations:{
		ADD_PERSON(state,value){
			console.log('mutations中的ADD_PERSON被調用了')
			state.personList.unshift(value)
		}
	},
	state:{
		personList:[
			{id:'001',name:'張三'}
		]
	},
	getters:{
		firstPersonName(state){
			return state.personList[0].name
		}
	},
}           

到這裡已經把vuex的内容準備好了

Count.vue 元件

<template>
	<div>
		<h1>目前求和為:{{sum}}</h1>
		<h3>目前求和放大10倍為:{{bigSum}}</h3>
		<h3>我在{{school}},學習{{subject}}</h3>
		<h3 style="color:red">Person元件的總人數是:{{personList.length}}</h3>
		<select v-model.number="n">
			<option value="1">1</option>
			<option value="2">2</option>
			<option value="3">3</option>
		</select>
		<button @click="increment(n)">+</button>
		<button @click="decrement(n)">-</button>
		<button @click="incrementOdd(n)">目前求和為奇數再加</button>
		<button @click="incrementWait(n)">等一等再加</button>
	</div>
</template>

<script>
	import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
	export default {
		name:'Count',
		data() {
			return {
				n:1, //使用者選擇的數字
			}
		},
		computed:{
			//借助mapState生成計算屬性,從state中讀取資料。(數組寫法)
			...mapState('countAbout',['sum','school','subject']),
			...mapState('personAbout',['personList']),
			//借助mapGetters生成計算屬性,從getters中讀取資料。(數組寫法)
			...mapGetters('countAbout',['bigSum'])
		},
		methods: {
			//借助mapMutations生成對應的方法,方法中會調用commit去聯系mutations(對象寫法)
			...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
			//借助mapActions生成對應的方法,方法中會調用dispatch去聯系actions(對象寫法)
			...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
		},
		mounted() {
			console.log(this.$store)
		},
	}
</script>

<style lang="css">
	button{
		margin-left: 5px;
	}
</style>
           

Person.vue 元件

<template>
	<div>
		<h1>人員清單</h1>
		<h3 style="color:red">Count元件求和為:{{sum}}</h3>
		<h3>清單中第一個人的名字是:{{firstPersonName}}</h3>
		<input type="text" placeholder="請輸入名字" v-model="name">
		<button @click="add">添加</button>
		<button @click="addWang">添加一個姓王的人</button>
		<button @click="addPersonServer">添加一個人,名字随機</button>
		<ul>
			<li v-for="p in personList" :key="p.id">{{p.name}}</li>
		</ul>
	</div>
</template>

<script>
	import {nanoid} from 'nanoid'
	export default {
		name:'Person',
		data() {
			return {
				name:''
			}
		},
		computed:{
			personList(){
				return this.$store.state.personAbout.personList
			},
			sum(){
				return this.$store.state.countAbout.sum
			},
			firstPersonName(){
				return this.$store.getters['personAbout/firstPersonName']
			}
		},
		methods: {
			add(){
				const personObj = {id:nanoid(),name:this.name}
				this.$store.commit('personAbout/ADD_PERSON',personObj)
				this.name = ''
			},
			addWang(){
				const personObj = {id:nanoid(),name:this.name}
				this.$store.dispatch('personAbout/addPersonWang',personObj)
				this.name = ''
			},
			addPersonServer(){
				this.$store.dispatch('personAbout/addPersonServer')
			}
		},
	}
</script>
           

App.vue

<template>
	<div>
		<Count/>
		<hr>
		<Person/>
	</div>
</template>

<script>
	import Count from './components/Count'
	import Person from './components/Person'

	export default {
		name:'App',
		components:{Count,Person},
		mounted() {
			// console.log('App',this)
		},
	}
</script>           

main.js 入口檔案

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入插件
import vueResource from 'vue-resource'
//引入store
import store from './store'

//關閉Vue的生産提示
Vue.config.productionTip = false
//使用插件
Vue.use(vueResource)

//建立vm
new Vue({
	el:'#app',
	render: h => h(App),
	store,
	beforeCreate() {
		Vue.prototype.$bus = this
	}
})
           

子產品化 + 命名空間 總結

目的:讓代碼更好維護,讓多種資料分類更加明确。

修改store.js

const countAbout = {
     namespaced:true,//開啟命名空間
     state:{x:1},
     mutations: { ... },
     actions: { ... },
     getters: {
       bigSum(state){
          return state.sum * 10
       }
     }
   }
   
   const personAbout = {
     namespaced:true,//開啟命名空間
     state:{ ... },
     mutations: { ... },
     actions: { ... }
   }
   
   const store = new Vuex.Store({
     modules: {
       countAbout,
       personAbout
     }
})           

開啟命名空間後,元件中讀取state資料:

//方式一:自己直接讀取
this.$store.state.personAbout.personlist
//方式二:借助mapState讀取:
...mapState('countAbout',['sum','school','subject']),           

開啟命名空間後,元件中讀取getters資料

//方式一:自己直接讀取
this.$store.getters['personAbout/firstPersonName']
//方式二:借助mapGetters讀取:
...mapGetters('countAbout',['bigSum'])           

開啟命名空間後,元件中調用dispatch

//方式一:自己直接dispatch
this.$store.dispatch('personAbout/addPersonWang',person)
//方式二:借助mapActions:
...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})           

開啟命名空間後,元件中調用commit

//方式一:自己直接commit
this.$store.commit('personAbout/ADD_PERSON',person)
//方式二:借助mapMutations:
...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'})           

代碼摘錄于尚矽谷Vue學習課件