Vuex状态管理工具(模块化开发)

一、以下是对vuex的理解,和工作流程图(如果已有了解直接跳过看实现代码)

Vuex 是一个用于状态管理的库,它是为 Vue.js 应用程序开发的,旨在帮助管理数据的流动和共享。

以下是对 Vuex 的一些关键概念的理解:

  1. 状态(State):单一状态树(State Tree)是存储整个应用程序状态的地方。状态是保存在 Vuex 中的集中式公共数据源,可以通过 this.$store.state 访问。它通常被看作是应用程序的唯一数据源。

  2. Getter:Getter 允许从存储在 Vuex 中的状态派生出新的状态。类似于 Vue 组件中的计算属性,Getter 可以对状态进行处理和计算,并将结果暴露给其他组件使用。

  3. Mutation:Mutation 是修改状态的唯一方式。Mutation 必须是同步函数,用于更改状态并跟踪状态变化。它们在提交时需要调用 commit 方法,并接收一个参数来传递数据载荷(Payload)。只有 Mutation 才能修改状态,这样确保了状态的变更可追踪和可维护性。

  4. Action:Action 用于处理异步操作或包含多个 Mutation 的复杂操作。Action 可以包含任意异步操作,例如从服务器获取数据后提交 Mutation 来更新状态。Action 在组件中通过调用 dispatch 方法来触发,可以接收一个 Promise,以便异步操作完成后再提交 Mutation。

  5. Module:Module 允许将 Vuex 分割成单个模块。每个模块拥有自己的状态、Getter、Mutation 和 Action,可以嵌套引用其他模块。这样组织代码可以更好地扩展和维护,并且可以在不同模块之间共享状态。

通过使用 Vuex,可以实现全局状态的集中管理,使不同组件之间能够方便地共享和更新状态。它提供了一种可预测的状态管理机制,简化了数据流的处理和调试过程,使应用程序的开发变得更加容易和可维护。

二、正式开始:首先创建一个store文件夹,创建一个index.js文件,引入Vue和Vuex,如果需要模块化开发就在index.js文件夹中引入创建的另外store仓库js文件,然后通过modules 把他们两个合并起来。

//该文件用于创建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
	}
})

 三、count仓库中有五大属性 分为 actions,mutations,state,getters,modules
1.actions 用于处理异步操作,比如axios请求,异步操作吗
2.mutations 用于对数据的加工处理。
3.state 用于初始化数据
4. getters 类似与计算属性,一般对加工完的数据在进行加工处理
5. modules 模块化开发
actions对象中接收到的函数可以接收两个参数,第一个是上下文对象,第二个是传递的数据,上下文中可以触发mutations中的方法
mutations对象中 方法可以接收到两个参数,第一个参数是state初始化的数据,第二个参数是action传递过来的数据.

//求和相关的配置
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
		}
	},
}

四、在页面中获取数据仓库数据或者派发数据方法方式:
第一种:通过vuex的优化函数获取数据或者派发方法
首先引入 四种方法,import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
在计算属性computed中可以展开 mapState, mapGetters 来获取数据
在methods 中可以展开 mapMutations mapActions 来派发actions方法,或者直接修改mutations中的数据
...mapState('countAbout',['sum','school','subject']), 第一个参数意思是从模块化modules中的countAbout 获取数据,第二个参数是 countAbout文件中获取state数据,是一个数组
method中 ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
第一个参数是模块化名字,第二个参数是键值对形式,键是ui页面中触发的方法,第二个参数是mutilation中对应的的方法 

<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>

五、 在页面中获取数据仓库数据或者派发数据方法方式:
第二种:通过原生的方式获取数据或者派发方法
第一步首先 需要在入口文件中引入store并把挂载到vm身上
然后就可以在页面中通过  this.$store.state.personAbout 获取personAbout
模块中的数据
通过this.$store.getters['personAbout/firstPersonName']获取仓库中的计算属性数据
通过this.$store.commit('personAbout/ADD_PERSON',personObj)
触发 personAbout仓库中mutions的方法 commit 是直接触发mutions方法中的函数,一般不需要异步操作就可以直接使用这种方式,
通过this.$store.dispatch('personAbout/addPersonWang',personObj)
触发 action中的异步方法

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
	}
})

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>

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
		}
	},
}

猜你喜欢

转载自blog.csdn.net/tianyhh/article/details/132321482