Vue3 - Vuex使用(一)

在这里插入图片描述
在这里插入图片描述

Vuex 适用于复杂的状态管理

Vue3里面安装指定版本

	npm  install vuex@next

Vuex的基本使用过程

简单版本
  • 创建与components同级的文件夹store / index.js
	import {createStore} from 'vuex'

	const store = createStore({
		state(){
			return{
				count:0
			}
		},
		mutations:{
			increment(state){
				state.count++
			},
			decrement(state){
				state.count--
			}
		},		
	})
	export default store
  • main.js 入口文件引入store
	import {createApp} from 'vue'
	import App from './App.vue'
	import store from './store'

	createApp(App).use(store).mount('#app')
  • Home.vue
	<template>
		<h2>{{$store.state.counter}}</h2>
		<button @click='increment'>+1</button>
		<button @click='decrement'>-1</button>
	</template>
	<script>
		import {mapMutatons} from "vuex"
		export default{
			setup(){
				const storeMutations = mapMutations(['increment','decrement'])
				return {
					...storeMutations
				}
			}
		}
	</script>

组件获取状态state

mapState 辅助函数

Home.vue

	<template>
		<h2> Home(computed):{{sCounter}}</h2>
		<h2>{{counter}}</h2>
		<h2> {{height}} </h2>
	</template>

Options API 实现

	<script>
		import {mapState} from 'vuex'
		1 or 2 or 3 or 4
	</script>
  1. 通过组件内计算属性取别名
	computed:{
		sCounter(){
			return this.$store.state.counter
		}
	}
  1. 通过mapState函数将所有vuex里的state属性拿到组件映射计算属性
	computed:mapState()
  1. mapState数组写法,保留组件自身计算属性➕其他vuex里的属性

    通过计算属性映射过来的属性,template里用的时候可以直接用{{counter}} 而不必加$store.state

	computed:{
		homeKey(){
			return 'home private key'
		},
		...mapState(["counter","age","height"])
	}
  1. mapState对象写法,可以给state里面的属性在组件内取别名(函数返回值的形式)
	computed:{
		...mapState({
			sCounter:state => state.counter
		})
	}

Componsition API 实现

	<script>
		import {computed} from 'vue'
		import {mapState,useStore} from 'vuex'
		// mapState返回值是一个对象,对象里面是一个一个的函数,函数调用后得到的是state里对应的属性值
		export default{
			setup(){
				const store = useStore()
				//1.直接用computed 映射
				const sCounter = computed(()=>store.state.counter)
				//2  mapState传入数组
				const storeStateFns = mapState(["counter","height","age"])
				const storeState = {}
				// 遍历
				Object.keys(stroeStateFns).forEach(fnKey=>{
					// 因为setup中没有this,此时必须传入{$store:state},将vuex的state手动指给调用函数
					const fn = storeStateFns[fnKey].bind({$store:state})
					storeState[fnKey] = computed(fn) // 转变为计算属性
				})
				return {
					sCounter,
					...storeState
				}
			}
		}
	</script>

将遍历state属性这段抽离成hooks / useState.js

	import {computed} from 'vue'
	import {mapState,useStore} from 'vuex'
	
	export function useState(mapper){
		const store = useStore()
		
		const storeStateFn = mapState(mapper)
		const storeState = {}
		
		Object.keys(storeStateFn).forEach(fnKey => {
			const fn = storeStateFn[fnKey].bind({$store:State})
			storeState[fnKey] = computed(fn)
		})
		return storeState
	}

组件中使用useState.js函数

	<script>
		import useState from '../hooks/useState'
		export default{
			setup(){
				const storeState = useState(["counter","age","height"])
				return {...storeState}
			}
		}
	</script>

getters的基本使用

组件内不直接使用vuex的属性,需要变化一下的时候使用getters

store / index.js

	import {createStore} from 'vuex'
	const store = createStore({
		state(){
			return{
				counter:0,
				books:[
				{
					name:"计算机组成原理",
					count:50,
					price:22
				},
					{
					name:"单片机开发实践",
					count:20,
					price:18
				},
				]
			}
		},
		mutations:{
			increment(state){
				state.counter++
			},
			decrement(state){
				state.counter--
			}
		},
		getters:{
			//求和
			totalPrice(state,getters){
				return state.books.reduce((pre,cur)=>{
					return pre+cur.count*cur.price
				},0)
			},
			nameInfo(state){
				return `name:${state.name}`
			}
		}
	})
mapGetters辅助函数

组件内使用

	<h2>总价值{{totalPrice}}</h2>
	<script>
		import {mapGetters} from 'vuex'
		export default{
			computed:{
				nameInfo(){ return this.$store.getters.nameInfo},
				computed:{...mapGetters},
				computed:{
					...mapGetters(["nameInfo","ageInfo","heightInfo"])
				},
				computed:{
					...mapGetters({
						sNameInfo:"nameInfo"
					})
				}
				
			}
		}
	</script>

Componsition API使用

	import {computed} from 'vue'
	import {mapGetters,useStore} from 'vuex'
	
	export default{
		setup(){
			const store = useStore()
			const sNameInfo = computed(()=>store.getters.nameInfo)
		
			const storeGettersFns = mapGetters(["nameInfo","ageInfo"])
			const sotreGettrs = {}
			Object.keys(storeGettersFns).forEach(fnKey = >{
				const fn = storeGettersFns[fnKey].bind({$store:store})
				storeGetters[fnKey]  = computed(fn)
			})
			return{
				sNameInfo,
				...sotreGettrs
			}
		}
	}

与useState很像,除了mapState 和 mapGetters不同,所以再抽出公用部分

hooks/index.js

	import {useState} from './useState'
	import {useGetters} from './useGetters'
	
	export {useState,useGetters}

hooks/useMapper.js

	import {computed} from 'vue'
	import {useStore} from 'vuex'
	
	export function useMappr(mapper,mapFn){
		const store = useStore()
		const storeStateFn = mapFn(mapper)
		const storeState = {}
		Object.keys(storeStateFn).forEach(fnKey => {
			const fn = sotreStateFn[fnKey].bind({$store:store})
			storeState[fnKey] = computed(fn)
		})
		return storeState
	}

hooks/useGetters.js

	import {mapGetter} from 'vuex'
	import {useMapper} from './useMapper'

	export function useGetters (moduleName,mapper){
		let mapperFn = mapGetters
		return useMapper(mapper,mapperFn)
	}

hooks/useState.js

	import {mapState} from 'vuex'
	import {useMapper} from './useMapper'
	export function useState (moduleName,mapper){
		let mapperFn = mapState
		return useMapper(mapper,mapperFn)
	}

组件内使用

	import {useGetters,useState} from '../hooks/index'
	setup(){
		const storeGetters = useGetters(["nameInfo","ageInfo","heightInfo"])	
		const storeState = useState(["counter","name","age","height"])
		return {
			...storeGetters,
			...storeState
		}
	}

Mutations基本使用

更改Vuex的store中的状态的唯一方法是提交mutations

Options API 使用
1.

	this.$store.commit("mutations里方法名",{传递的参数对象})

2

	this.$store.commit({
		type:"mutations里方法名",
		age:12,
		...传递参数
	})

一般多个地方要用到同一个变量名字的时候,可以将其封装为常量文件

store / mutations-type.js

	export const INCREMENT_N = "increment_n"

store / index.js

	import {INCREMENT_N} from "./mutations-type'
	
	mutations:{
		[INCREMENT_N](state,payload){
			state.counter += payload.n
		}
	}
mapMutations辅助函数

组件内使用
mapMutations返回的是一个对象,对象里面是一个函数,方法绑定也是函数,不必再转换了

	<button @click='increment_n({n:10)'>+10</button>
	<script>
		import {mapMutations} from 'vuex'
		import {INCREMENT_N} from '../store/mutations-type'
		
		export default{
			setup(){
				const storeMutations = mapMutations(['increment','decrement',INCREMENT_N])
				return {
					...storeMutations
				}
			}
		}
	</script>

Actions

异步操作都放在这里,比如网络请求

actions 与 mutations的区别:
  • actions 提交的是mutations,而不是直接更改state里面的状态
  • actions 可以包含任意异步操作
actions使用

组件内

	methods:{
		this.$store.dispatch("actions里面的名字",{传递的参数,可以不传})
	}

store / index.js

	import {createStore} from 'vuex'
	const store = createStore({
		state(){
			return{
				banners:[]
			}
		},
		mutations:{
			increment(state,payload){
				state.counter++
			}
		},
		actions:{
			incrementAction(context,payload){
				//异步操作
				setTimeout(()=>{
					context.commit("increment")
				},1000)
			}
		}
	})
  • context 里面都有什么?
name含义用法
commit调用mutations里的方法commit("") 等同于 context.commit()
dispatch调用actions里面的其他方法dispatch()
getters获取getters里面某一个属性getters() 等同于 context.getters()
state获取state里面的值
  • context 解构
	actions:{
		decrementAction({commit,dispatch,state}){
			commit("decrement")
		}
	}

组件中使用actions里面方法的另一种写法

	methods:{
		decrement(){
			this.$store.dispatch({
				type:"decrementAction"
			})
		}
	}
mapActions辅助函数

组件中使用

	<script>
		import {mapActions} from 'vuex'
		export default{
			methods:{
				...mapActions(["decrementAction","incrementAction"]),
				...mapActions({
					add:"incrementAction",
					sub:"decrementAction"
				})
			},
			setup(){
				const actions = mapActions(["decrementAction","incrementAction"])
				
				return{
					...actions
				}
			}
		}
	</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值