Vue 学习
Vue 05 vuex
01 介绍
1、概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
2、什么时候使用Vuex
① 多个组件依赖于同一状态
② 来自不同组件的行为需要变更同—状态
多组件共享数据——全局事件总线实现
下图是BCD读到A中的数据
下图,所有人都可以 读、写 X
多组件共享数据——VueX总线实现
vuex不属于任何一个组件(A B C D App)
02 工作原理(原理图)
action 本质是对象;mutation本质是对象;state 状态,等于数据。本质是一个对象。 **他们仨是被 store管理的。despatch、commit是store提供的。**需要让所有的VC都可以访问到 store
以下面的求和案例讲解:
vue允许你可以直接调用mutations(action的作用是,如果除法的除数来自另一台服务器,那么在他这里发送请求)
vc:客人;Action服务员;Mutation后厨; State菜。
使用
① npm i vuex
注意,在2022年2月,vue3成为了默认版本,也就是说 执行 npm i vue时安装的直接就是vue3。并且vue3 成为默认版本的同时,vuex也升级到了4版本。npm i vuex安装的是vuex4。 vuex4 只能在 vue3 上使用,如果我们在一个vue2项目中安装vuex4 就会报错。
**vue2中,要用vuex的3版本。vue3中,要用vuex的4版本。**视频教学中使用的是vue2所以要安装vuex3版本。npm i vuex@3
② Vue.use(Vuex)
在use了vuex之后,创建vm的时候就可以传入配置项 store了
③ store
创建store
方法① src下创建文件夹 vuex,vuex文件夹张创建空白的 store.js
方法② src下创建文件夹 store,store下创建空白 index.js
要先创建vuex实例,再创建store
④ vc==>store
Q:为什么 这么配置就能保证组件能访问到?因为这个store作为 new Vue 的配置对象,我能理解 vm 可以访问到,但是所有 vc 是怎么访问到的?之前的全局总线配置在了 Vue.prototype 中所以 所有vc可以访问,这次是为什么?
感觉这一篇比较好的解释了。https://blog.csdn.net/dyw3390199/article/details/115207165
03 案例
求和
补充HTML
双向数据绑定,复选框的值 要通过value定义
纯vue实现
- MyCount.vue
<template>
<div>
<h1>当前求和为:{{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="increment">+</button>
<button @click="decrement">-</button>
<button @click="incrementOdd">当前求和为奇数再加</button>
<button @click="incrementWait">等一等再加</button>
</div>
</template>
<script>
export default {
name:'MyCount',
data() {
return {
n:1, //用户选择的数字
}
},
methods: {
increment(){
this.sum += this.n
},
decrement(){
this.sum -= this.n
},
incrementOdd(){
if(this.sum % 2){
this.sum += this.n
}
},
incrementWait(){
setTimeout(()=>{
this.sum += this.n
},500)
},
},
watch: {
n(value) {
console.log(value);
}
}
}
</script>
vuex使用
配置好vuex、保证每一个VC身上都有store之后:
- 以加法为例
MyCount.vue
<template>
<div>
<!-- 最后一步 使用修改之后的state。注意这里不用写this -->
<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="increment">+</button>
</div>
</template>
<script>
export default {
name:'MyCount',
data() {
return {
n:1, //用户选择的数字
// ************************************************************
// 步骤一 为了演示vuex,把本例中的 sum 放去了 /src/store/index.js
// sum:0 当前的和
}
},
methods: {
increment(){
this.$store.dispatch('jia', this.n)
// ************************************************************
// 步骤二 dispatch
// (步骤三 去/src/store/index.js中让 actions 里面配置好函数)
// this.sum += this.n
}
}
</script>
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const actions = {
jia(context,value) {
console.log('actions中的jia被调用了',context,value);
context.commit('JIA',value) // 提交
// 开发技巧 JIA写大写
}
}
const mutations= {
// 开发技巧 JIA写大写
JIA(state, value){
console.log('mutation中的JIA');
state.sum += value
console.log(state.sum );
},
}
const state = {
sum:0 //当前的和
}
export default new Vuex.Store({
actions,
mutations,
state
})
组件中直接调用commit和mutations对话:注意这里需要大写
04 getters配置项
Store中的配置项 getters
getters——用于将state中的数据进行加工 可以视作计算属性
总结:
1、概念:当state中的数据需要经过加工后再使用时,可以使用getters加工。
2、在 store.js 中追加 getters 配置(得写返回值)
3、组件中读取数据:$store.getters.bigSum
05 mapState 与 mapGetters
为什么要引入mapState 与 mapGetters?
在我们的代码中,我们把共有的状态(数据)写在了 store/index.js 上。于是在组件中想对数据进行一些计算的时候,可以用上一节的 getters 配置项。
但是不同的组件对 store/index.js 里的数据想有不同的计算操作。于是在computed中对 **this. s t o r e . s t a t e . x x x ∗ ∗ 进行一些简单的计算,(注意如果在插值语法中就不需要写 t h i s ,直接写 store.state.xxx** 进行一些简单的计算,(注意如果在插值语法中就不需要写this,直接写 store.state.xxx∗∗进行一些简单的计算,(注意如果在插值语法中就不需要写this,直接写store.state )。
当 this. s t o r e . s t a t e . x x x 使用的多了以后我们就开始思考,有没有什么办法可以不写共有部分的 t h i s . store.state.xxx 使用的多了以后我们就开始思考,有没有什么办法可以不写共有部分的this. store.state.xxx使用的多了以后我们就开始思考,有没有什么办法可以不写共有部分的this.store.state。vue就提供了mapState 与 mapGetters方法。
补:ES6语法
let obj2 = {x:100, y:200}
let obj1 = {
a:1,
b:2,
...obj2,
c:3
}
mapState使用
- 写法一:借助mapState生成计算属性,从state中读取数据(对象写法)
如果自己写计算属性的话,在开发工具中, 会算作计算属性。如果是用vuex,他会:但其实也是算作计算属性的
请注意:这里不可以简写。对象里面是 key:value,而这里找的不是sum变量 key: sum,而是用sum这个名称找, key:‘sum’。以及虽然key肯定是字符串,但是可以不用写单引号
- 写法二:数组写法
mapGetters
总结
mapState和mapGetters写在组件的computed属性中。
先引入 import {mapState,mapGetters} from 'vuex'
1、mapState方法: 用于帮我们映射state中的数据为计算属性
2、mapGetters方法: 用于帮我们映射getters中的数据为计算属性
06 mapActions 与 mapMutations
mapMutations
HTML:
<button @click="increment(n)">+</button>
如果这里不传参,在点击了之后 他会自动传递一个参数 event
引入:
import {mapMutations} from 'vuex'
methods:
对象写法
数组写法:
...mapMutations(['JIA', 'JIAN'])
// 要和 mutations中保持一致
mapActions
总结
1、 mapActions方法:用于帮助我们生成与actions对话的方法,即包含 $store.dispatch(xxx) 的函数
2、mapMutations方法:用于帮助我们生成与mutations对话的方法,即包含$store.commit(xxx) 的函数
备注: mapActions与mapMutations使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。
07 多组件共享数据
MyPerson组件、MyCount组件
V:\Web\Vue_\myCode_Vue2\vue_test\28_src _多组件共享数据
08 vuex模块化
MyPerson组件(人员相关)、MyCount组件(求和相关)
- store/index.js
-
模块化之后,之前的 MyCount需改为:
这里只需要加一个命名空间就可以了
- MyPerson需改为:
state中的数据,getters中的计算属性,commit,dispatch
这里不仅仅需要命名空间,每一个是不一样的