Vuex统一管理状态

1、vuex 是什么

实现数据共享

是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享。

概念:在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 vue 应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。


不使用Vuex和使用Vuex:
在这里插入图片描述
使用Vuex统一管理状态的好处:
①能够在 vuex中集中管理共享的数据,易于开发和后期维护
②能够高效地实现组件之间的数据共享, 提高开发效率
③存储在vuex中的数据都是响应式的,能够实时保持数据与页面的同步

2、vuex 工作原理图

在这里插入图片描述

3、搭建vuex环境

npm i vuex

main.js

// 引入store
import store from './store'

new Vue({
	el: '#app',
	render: h => h(App),
	store,
})

vuex 放在项目的 store文件夹中

store/index.js

import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
// 应用Vuex插件
Vue.use(Vuex)

// 用于响应组件中的动作
const actions = {}
// 用于操作数据(state)
const mutations = {}
// 用于存储数据
const state = {}

// 创建并暴露store
export default new Vuex.Store({
	actions,
	mutations,
	state,
})

注意:需要在 store/index.js 应用Vuex,不然在main.js 中应用Vuex,但 import store from './store'会先解析,会出错。

在文件中,import … from … 无论放任何位置,都会先被解析。

4、关于 actions、mutations、state

state

  • vuex 管理的状态对象
  • 它应该是唯一的

actions

  • 值为一个对象,包含多个响应用户动作的回调函数
  • 通过 commit( )来触发 mutation 中函数的调用, 间接更新 state
  • 如何触发 actions 中的回调?

在组件中使用: $store.dispatch(‘对应的 action 回调名’) 触发

  • 可以包含异步代码(定时器, ajax 等等)

mutations

  • 值是一个对象,包含多个直接更新 state 的方法
  • 谁能调用 mutations 中的方法?如何调用? 在 action 中使用:commit(‘对应的 mutations 方法名’) 触发
  • mutations 中方法的特点:不能写异步代码、只能单纯的操作 state

案例:

Count.vue

<template>
	<div>
		<h1>当前数值为:{{ $store.state.sum }}</h1>
		<select v-model.number="n">
			<option value="1">1</option>
			<option value="2">2</option>
			<option value="3">3</option>
		</select>
		<button @click="myclick">+</button>
		<button @click="Waitclick">1s后+</button>
data() {
	return {
		n: 1,
	}
},
methods: {
	myclick() {
		// this.$store.dispatch('jia',this.n)
    // 若无动作,可以直接commit
		this.$store.commit('JIA',this.n)
	}
	Waitclick() {
		this.$store.dispatch('waitjia',this.n)
	}
}

store/index.js

import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
// 应用Vuex插件
Vue.use(Vuex)

// 用于响应组件中的动作
const actions = {
	// jia(context, value) {
		// context.commit('JIA', value)
	// }	
	waitjia(context, value) {
		// console.log(context)  {getters: {…}, state: {…}, rootGetters: {…}, dispatch: ƒ, commit: ƒ, …}
		// 业务逻辑后commit
		setTimeout(() => {
			context.commit('JIA', value)
			// 也可以不按标准,直接在actions中改state,但是开发者工具是连接mutations的,开发者工具将失效,所以不要这样写。
			// context.state.sum += value
		}, 1000)
	}	
}
// 用于操作数据(state)
const mutations = {
	// mutations中函数一般用大写
	JIA(state, value) {
		state.sum += value
	}
}
// 用于存储数据
const state = {
	sum: 0
}

// 创建并暴露store
export default new Vuex.Store({
	actions,
	mutations,
	state,
})

若actions 中要处理很多业务逻辑,

则可以用到 context 中的 dispatch(),相当于用很多服务员。

// 用于响应组件中的动作
const actions = {
	waitjia(context, value) {
		console.log('处理了一些事情')
		context.dispatch('demo1', value)
	},
	demo1(context, value) {
		console.log('我又哈哈哈处理了一些事情')
		context.dispatch('demo2', value)
	}	
	demo2(context, value) {
		setTimeout(() => {
			context.commit('JIA', value)
		}, 1000)
	}	
}

为什么逻辑要写在actions中呢,因为如果很多组件都要这个逻辑,就会每个组件都要在methods中写逻辑,很麻烦,逻辑写在actions中,就可所有组件用,方便省事。

5、getters配置项

  1. 值为一个对象,包含多个用于返回数据的函数

  2. 如何使用?—— $store.getters.xxx

getters 用于将state中的数据进行加工

const getters = {
	bigSum(state) {
		return state.sum*10
	}
}

使用:

<h1>数字放大10倍为:{{ $store.getters.bigSum }} </h1>

6、mapState与mapGetters

<h1>当前数值为:{{ $store.state.sum }} </h1>

<h1>数字放大10倍为:{{ $store.getters.bigSum }} </h1>

这样写很麻烦,总是有$store.state.$store.getters.

所以这样:

<h1>当前数值为:{{ aa }} </h1>

<h1>学校:{{ bb }} </h1>

<h1>数字放大10倍为:{{ cc }} </h1>

computed: {
	aa() {
		return this.$store.state.sum
	},
	bb() {
		return this.$store.state.school
	},
	cc() {
		return this.$store.getters.bigSum
}

可是这样也很麻烦,需要在computed 中写很多$store.state.$store.getters.

所以用到了mapState 与 mapGetters

Count.vue

import { mapState, mapGetters } from 'vuex'
computed: {
	// 借助mapState生成计算属性(对象写法)
	//...mapState({aa:'sum', bb: 'school'}),
	// 借助mapState生成计算属性(数组写法)
	...mapState(['sum','school']),
  // 即对象写法中的...mapState({sum:'sum', school: 'school'}), 可以命名相同。

	...mapGetters(['bigSum']),
}

x对象中放y对象,y前需要加 ... 就相当于将y展开放入x

7、mapActions与mapMutations

methods: {
	myclick() {
		this.$store.commit('JIA',this.n)
	},
	sheclick() {
		this.$store.commit('JIAN',this.n)
	}
	Waitclick() {
		this.$store.dispatch('waitjia',this.n)
	}
}

this.$store.commit若写很多也很麻烦,所以为了省略写this.$store.commit

用到了mapActions与mapMutations

import { mapActions, mapMutations } from 'vuex'
methods: {
	// (对象写法)
	...mapMutations({myclick: 'JIA', sheclick: 'JIAN'}),
	// (数组写法)
	// ...mapMutations(['JIA', 'JIAN']),

	// mapActions同上
	...mapActions({Waitclick: 'waitjia'}),

但是需要传值

<button @click = "myclick(n)">+</button>
<!-- (数组写法)-->
<!-- <button @click = "JIA(n)">+</button> -->

<button @click="Waitclick(n)">1s后+</button>

8、多组件共享数据

9、vuex模块化

看下面例子
在这里插入图片描述
index.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

// 引入小仓库
import home from './home'
import detail from './detail'

export default new Vuex.Store({
    modules: {
        home,
        detail,
    }
})

detail.js

// detail 模块的小仓库
import {
    reqGoodsInfo
} from "@/api"

// state:仓库存储数据的地方
const state = {
    goodInfo: {},
}
// mutations:修改state的唯一手段
const mutations = {
    GETGOODINFO(state, goodInfo) {
        state.goodInfo = goodInfo
    },

}
// actions:处理action,书写自己的业务逻辑、也可以处理异步
const actions = {
    // 获取产品信息
    async getGoodInfo({
        commit
    }, skuId) {
        // 向服务器发请求
        let result = await reqGoodsInfo(skuId)
        if (result.code == 200) {
            commit("GETGOODINFO", result.data)
        }
    }
}
// getters:计算属性,用于简化仓库数据,让组件获取仓库的数据更方便
const getters = {
    categoryView(state) {
        // 需要加上 || {},否则若没请求到数据,则会报错
        return state.goodInfo.categoryView || {};
    },
    skuInfo(state) {
        return state.goodInfo.skuInfo || {};
    },
}

// 对外暴露
export default {
    state,
    mutations,
    actions,
    getters,
}

main.js

// 引入仓库
import store from "@/store"

Dedail/index.vue

......
......
import { mapGetters } from "vuex";

export default {
  name: "Detail",
  data() {
    return {
      skuNum: 1,
    };
  },
  mounted() {
    this.$store.dispatch("getGoodInfo", this.$route.params.skuid);
  },
  computed: {
    ...mapGetters(["categoryView", "skuInfo"]),
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

欢莱

为您解决问题,此项目我成功完成

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值