Vuex的使用教程
一、理解Vuex
vuex是什么
什么时候使用Vuex
- 多个组件依赖于同一状态
- 来自不同组件的行为需要变更同一状态
求和案例-纯Vue版
option的value引号里面的东西会被当成字符串进行拼串操作,无法正常进行加减操作。
在value前面加上冒号就可以解决这个问题
方法一:加冒号
其实就是v-bind的一个运用,加上冒号之后,引号里面的内容都当成js表达式去解析
方法二:加修饰符
收集到的东西强制转换成number类型
vuex工作原理
vuex有三个组成部分:
Actions、Mutations、State,这三个都是对象类型。这三个对象经由store仓库管理
调用的dispatch和commit都是store提供的
- Actions:写业务逻辑,比如奇数时再加,等一等再加
- Mutations:真正的修改操作
这里的Actions看似有点多余,其实不然。
当调用了dispatch,只给了'jia'参数,要加的那个数需要发送ajax请求(异步请求)才能获取的时候,就需要在Actions里面发送请求
在动作类型和动作值都具备的情况下,Vue允许在组件VC直接调用commit和Mutations进行对话,只是图上没有体现
Devtools:vuex官方出的开发者调试工具
二、搭建Vuex环境
1. installing
因为现在vue默认为vue3版本,对应的vuex默认也更新为vuex4。但我们使用的是vue2,下载时必须指定安装vuex3版本,否则会报错
npm i vuex@3
2. 使用插件
在main.js中引入并使用插件
import 'Vuex' from 'vuex'
Vue.use(Vuex)
在Vue.use了Vuex之后,创建vm的时候就可以传入store这个配置项了
(因为这时所有的vc和vm都可以看到store)
3. 让vc和vm可以看见store
创建一个名为store的文件夹,里面包含了index.js文件
//该文件用于创建Vuex中最为核心的store
//对象值的key和保存对应值的变量重名了可以触发对象的简写形式
//引入Vuex
import Vuex from 'vuex'
//准备actions——用于响应组件中的动作
const actions = {};
//准备mutations——用于操作数据(state)
const mutations = {};
//准备state——用于存储数据
const state = {};
export default new Vue.Store({
actions,
mutations,
state,
})
这样写的非常齐全的store浏览器依旧会报错,这是因为main.js中import顺序的问题
要求先调用Vue.use(),再创建store实例
但其实修改了顺序之后控制台依旧报错,这是脚手架解析import语句的问题
在脚手架里面写import,不管两个import之间写了什么代码,它会扫描整个文件的import语句,把所有import语句,按照编写的顺序全部汇总到最上方。
所以调整代码顺序也没有用
解决方案:
在index.js文件创建store之前引入并使用Vuex
求和案例-vuex版
store的index.js文件
1. 响应组件中的动作
//该文件用于创建Vuex中最为核心的store
//对象值的key和保存对应值的变量重名了可以触发对象的简写形式
//引入Vue
import Vue from 'vue';
//引入Vuex
import Vuex from 'vuex'
//使用Vuex插件
Vue.use(Vuex)
//准备actions——用于响应组件中的动作
const actions = {
jia(context, value) {
context.commit('JIA', value);
}
};
//准备mutations——用于操作数据(state)
const mutations = {
JIA(state, value) {
state.sum += value;
}
};
//准备state——用于存储数据
const state = {
sum: 0
};
export default new Vuex.Store({
actions,
mutations,
state,
})
actions对象中的jia函数接收两个参数:
- context类似于miniStore,是一个上下文环境,让我们可以在actions里面调用commit接口
- 第二个参数就是操作值
在开发中,一般用大小写来区分是哪个对象里面的函数:
- 小写是actions里面的
- 大写是mutations里面的
mutations对象中的JIA函数接受两个参数:
- state对象(里面多了getter和setter,目的就是为了检测数据的变化)
- 操作值
2. 显示store里面的数据
{{$store.state.sum}}
注意:模板里面不用写this,模板里面可以看见vc里面的所有东西
我们现在把业务逻辑都写在actions里面
//引入Vue
import Vue from 'vue';
//引入Vuex
import Vuex from 'vuex'
//使用Vuex插件
Vue.use(Vuex)
//准备actions——用于响应组件中的动作
const actions = {
jia(context, value) {
context.commit('JIA', value);
},
jian(context, value) {
context.commit('JIAN', value);
},
jiaOdd(context, value) {
if (context.state.sum % 2) {
context.commit('JIA', value);
}
},
jiaWait(context, value) {
setTimeout(() => {
context.commit('JIA', value);
}, 500);
}
};
//准备mutations——用于操作数据(state)
const mutations = {
JIA(state, value) {
state.sum += value;
},
JIAN(state, value) {
state.sum -= value;
}
};
//准备state——用于存储数据
const state = {
sum: 0
};
export default new Vuex.Store({
actions,
mutations,
state,
})
现在我们来对代码进行优化,actions对象中的jia函数和jian函数并没有什么动作,我们可以直接让其和mutations沟通
在组件中就不使用dispatch了,而是直接调用commit联系mutations,注意JIA要大写哦!!
vuex的基本使用
三、store配置项
getters
用于将state中的数据进行加工
我们希望增添一行显示sum计算过后的一个值(比如放大十倍),可以直接用插值语法+js表达式来实现。
但是逻辑运算复杂时就不能这样了(比如*10 + 9 - 2 / 100 再开方),此时可以用计算属性来解决。
但是计算属性只有自己这个组件才能复用,跨组件不能用。此时可以用store的getters配置项来解决
const getters = {
bigSum(state) {
return state.sum * 10;
}
}
- 可以拿到state参数
- 跟计算属性很像,需要靠return来返回计算的值
state ——> data
getters ——> computed
mapSate和mapGetters
为优化$store.state类似代码的重复编写,我们将其写成以下计算属性的形式
但是写好之后我们发现,还是非常冗余而且有很多代码的重复。
我们希望实现一个函数,传入两个参数(我们想要的名称,在store.state里面的名称)就可以自动帮我们生成上段代码获取到数据
——引入mapState,它就能实现以上功能
借助mapState生成计算属性,从state中读取数据
import {mapState} from 'vuex'
1. 对象写法
因为mapState的返回值是一个对象,不能在对象里面写对象,所以这里运用扩展运算符
2. 数组写法
computed: {
//自己写computed属性
// sum() {
// return this.$store.state.sum
// },
// school() {
// return this.$store.store.school
// },
// subject() {
// return this.$store.store.subject
// },
// bigSum() {
// return this.$store.getters.bigSum
// }
//借助mapState生成计算属性,从state中读取数据(对象写法)
// ...mapState({ he: 'sum', xuexiao: 'school', xueke: 'subject' })
//借助mapState生成计算属性,从state中读取数据(数组写法)
...mapState({sum:'sum',school:'school',subject:'subject'})
},
易错:
这里可不可以简写成
不可以,只有 sum : sum(后面是变量名)的时候才能这样简写,此时我们的键值是字符串,如果这样写是无法成功解析成我们想要的键值对的
正确简写方式:
...mapState(['sum','school','subject'])
mapGetters的用法如上,不再赘述
mapMutations和mapActions
优化methods里面的代码
——引入mapMutations
借助mapMutations生成对应的方法,方法中会调用commit去联系mutations
1. 对象写法
以下是我们希望它帮我们生成的代码
但它实际帮我们生成的
这样会报错,我们来分析一下
不写小括号也会传参(event),当你点击时event就是鼠标事件,如下。于是乎就乱套了
解决方法:
其实还有一种nt写法
2. 数组写法
同样的,必须键值对值一样才可以这样写
注意:要写mutations里面的那个名称
mapActions:
借用mapActions生成对应的方法,方法中会调用dispatch去联系actions
总结
四、Vuex模块化
问题:
当项目变得庞大,组件数量变多时,这个mutations就会变得难以维护
并且所有程序员都操作这一个mutations会造成git版本控制的冲突
所以我们的目标是把不同分类的mutation放在不同的位置
将其暴露出去
获取数据
方式一:
方式二:
通过第一个参数去指定分类,获取后面的数据
但是,此时出现了报错
原因:
当你想通过第一个参数去指定分类,获取后面的数据的时候
你在配置Vuex的时候,在每一个配置里面都加上一个特殊的配置项——
namespaced: true
写上这个配置项之后,a、b两个分类名才能mapState认识
通知调用mutations和actions里面的函数时也要记得写上分类名
没有用到map方法时如何调用模块化
特别注意分类名是在state后面的!!!
我们再来看一个情景,在getters里面对state中的数据进行加工,通过getters获取到name的first Name,如下写法(错误)
这是因为getters里面的分类和state里面的分类有所不同
所以getters里面压根就没有'personAbout'这个属性名,只有personAbout/firstPersonName
但是以上写法仍然是错误的,因为读取对象属性使用点语法时,不能有斜杠
读取对象属性的另一种方法:
方括号里面写字符串
总结
原文地址:https://blog.csdn.net/ixxoic/article/details/144352182
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!