VUE笔记(九)vuex
一、vuex的简介
1、回顾组件之间的通讯
父组件向子组件通讯:通过props实现
子组件向父组件通讯:通过自定义事件($emit)方式来实现
兄弟组件之间的通讯:事件总线($eventBus)、订阅与发布方式来实现
跨级组件的通讯:可以通过(provider和inject)方式来实现
2、什么是Vuex
3、使用vuex的好处
-
集中管理共享数据
-
高效实现组件之间数据共享
-
vuex中的数据都是响应式的,能够实施保持数据与页面的同步
4、vuex和localStorage的区别
-
vuex是存储在内存中,localStroage存储数据在浏览器本地存储的
-
vuex的数据是瞬时的,localStroage是持久的,是不容易丢失的
-
vuex的数据是响应式的,localStorage中的数据不是响应式的
-
vuex还能完成异步操作(网络请求的),localStorage仅仅只是一个保存数据和获取数据
-
vuex中数据按照业务进行模块化,localStorage管理数据没有模块化
-
vuex直接操作JS的对象无需转换,localStorage存储数据要转成JSON,取数据要将JSON转成JS对象
-
单页面应用的程序组件数据共享使用使用状态机(vuex),localStorage适合多【页面数据的共享
5、什么情况下我应该使用 Vuex?
Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。 如果您不打算开发大型单页应用,使用 Vuex 可能是繁项几余的。确实是如此一一如果您的应用够简单,您最好不要使用 Vuex,一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择,引用 Redux的作者 Dan Abramov 的话说就是:
Flux 架构就像眼镜: 您自会知道什么时候需要它
6、vuex的安装和基本配置
-
下载vuex的依赖包
npm i vuex@3.6.2
-
在src目录下创建一个store文件夹
-
在src/store/index.js在此处完成vuex状态机仓库的基本配置
import Vue from 'vue'
import Vuex from 'vuex'
//将vuex以插件的方式设置到Vue中
Vue.use(Vuex)
/*创建仓库new Vuex.Store(参数)参数是状态机配置对象,状态机由5大部件组成state:用来管理vuex仓库(store)中的状态,它是一个对象mutation:用来操作state的选项,改变数据,它是一个对象actions:异步操作的getters:相当于是状态机中的计算属性modules:模块化
*/
const store=new Vuex.Store({state:{num:10},mutations:{}
})
//导出store
export default store
-
挂载store到vue中
import Vue from 'vue'
import App from './App.vue'
import store from '@/store'
Vue.config.productionTip = false
new Vue({render: h => h(App),store
}).$mount('#app')
二、vuex的基本使用和原理
1、Store核心概念
-
state:用来存储状态的
-
Mutatations:State的数据只能通过Mutations才能改变
-
Actions:用来完成异步操作,比如从后端获取数据
2、vuex的原理
Vuex的执行的流程
-
VueComponents(Vue组件)通过执行dispatch向store对象的Actions发送命令,要求完成异步任务
-
Actions执行异步任务,比如向Backend API(后端)发送请求,从后端获取到结果
-
Actions通过执行commit要求Mutations更改State状态机的数据,Mutatations就开始执行这个操作
-
Vue Componetents(Vue组件)直接从仓库中获取数据
注意点:
-
如果不执行异步任务,组件可以直接操作Mutatation来完成仓库中数据的改变
3、vuex的基本操作
这里以计数器的方式来讲解这个案例
3.1、state
-
首先先在store/index.js的state部分定义状态机状态数据
const store=new Vuex.Store({state:{num:10}
})
-
在组件中获取这个状态数据
组件中如果要获取store中的state数据的语法
如果要在js代码部分获取
this.$store.state.数据名
如果要在template部分获取
{{$store.state.数据名}}
或者
<div v-bind:属性="$store.state.数据名"></div>
3.2、mutations
组件中操作状态机的数据
如果组件内要更改状态机的数据,如果是通过的话,直接通过Mutations的方式去操作
-
在store对象配置对象中添加mutations选项,并定义要操作的方法
const store=new Vuex.Store({state:{num:10},mutations:{INCREMENT(state,payload){state.num++}}
})
参数说明
1) 参数1:state对象
2) 参数2:载荷数据,此数据来源于组件或者actions
-
组件中操作state的数据
this.$store.commit(方法名,传递的参数)
export default {methods:{increment(){this.$store.commit('INCREMENT')}}
}
-
如果组件需要给仓库中传递数据,可以通过载荷传值
const store=new Vuex.Store({state:{num:10},mutations:{INCREMENT_N(state,payload){state.num+=payload}}
})
export default {methods:{incrementN(n){this.$store.commit('INCREMENT_N',3)}}
}
3.3、actions
组件中要调用store仓库中的actions的语法
this.$store.dispatch('actions的相关方法名',参数)
购物车案例
-
组件
<template><div><h2>购物车列表</h2>{{$store.state.shopcartList}}<table><thead><tr><td>ID</td><td>名称</td><td>数量</td><td>价格</td><td>小计</td></tr></thead><tbody><tr v-for="(item,index) in $store.state.shopcartList" :key="item._id"><td>{{index+1}}</td><td>{{item.name}}</td><td>{{item.num}}</td><td>{{item.price}}</td><td>{{item.num*item.price}}</td></tr></tbody></table></div>
</template><script>
export default {methods:{getShopcartList(){//调用store仓库中的actions,让其执行异步操作this.$store.dispatch('getShopcartList_Async')} },created(){this.getShopcartList()}
}
</script><style></style>
-
store
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store=new Vuex.Store({state:{shopcartList:[]},mutations:{getShopcartList_Sync(state,payload){console.log('------2、store中的mutations的getShopcartList_Sync--------------');console.log('payload',payload);state.shopcartList=payload}},//完成异步操作actions:{async getShopcartList_Async(context){console.log('------1、store中的actions的getShopcartListAsync--------------');let result=await Vue.prototype.$api.shopcart.getShopcartData()console.log(result.data);console.log('context',context);context.commit('getShopcartList_Sync',result.data)}}
})
//导出store
export default store
3.4、getters
getters选项中专门是依赖于state数据,产生新的数据,就相当于组件中计算属性
语法
const store=new Vuex.Store({getters:{getter方法名称(state){return 处理后的数据}}
})
在组件中调用的语法
this.$store.getters.getter方法名称
案例:使用getters完成总价计算
const store=new Vuex.Store({getters:{totalPrice:state=>state.shopcartList.filter(item=>item.checked).reduce((prev,cur)=>prev+cur.price*cur.num,0)}
})
组件中方法问
总价:{{$store.getters.totalPrice}}
三、辅助函数
之前我们如果要在组件中访问状态机仓库中的数据,或者操作状态机仓库的数据,必须通过this.$store这个对象来完成,除了这种方式之外,vuex为我们提供了另外一种组件中访问或者操作store的方式,这种方式就是辅助函数
辅助函数最重要的思想是将状态机中的数据或者方法映射成组件内方法
vuex中提供了以下四种常用方法
-
mapState():这个方法就是将状态机仓库中的state数据映射成组件内数据
-
mapMutatations():将状态机仓库中mutations选项中方法映射组件的方法
-
mapActions():将状态机仓库中actions选项中的方法映射成组件的方法
-
mapGetters():将状态机仓库中getters选项中的方法映射成组件内的计算属性
1、mapActions的使用
-
导入mapActoins
import {mapActions} from 'vuex'
-
在methods选项中使用扩展运算符来映射仓库中的actions选项的方法到组件中
export default{methods:{...mapActions(["仓库中actions选项中的对应的方法名"])}
}
-
直接调用
export default{methods:{...mapActions(["getShopcartList_Async"]),getShopcartList(){this.getShopcartList_Async()}}
}
2、mapState的使用
-
导入mapState
import {mapState} from 'vuex'
-
必须在计算属性中使用扩展运算符来进行映射
语法
computed:{...mapState(['state中的属性名'])
}
案例
export default {computed:{...mapState(["shopcartList"])}
}
-
组件中直接使用
{{shopcartList}}
3、mapMutations
-
导入mapMutations
import {mapMutations} from 'vuex'
-
必须在methods中使用扩展运算符的方式将其映射成组件中相关方法
export default {methods:{...mapMutations(["increment_Sync"]),increment(){this.increment_Sync()}}
}
4、mapGetters
-
导入mapGetters
import {mapGetters} from 'vuex'
-
在computed选项中使用扩展运算符将其映射
export default {computed:{...mapGetters(["totalPrice"])},
}
5、别名
如果你映射仓库中的名字正好和你的组件内的名子冲突了怎么办
export default{methods:{...mapMutations({"新名称1":"仓库中名称"}),...mapActions({"新名称1":"仓库中名称"})},compouted:{...mapState({"新名称1":"仓库中名称"}),...mapGetters({"新名称1":"仓库中名称"})}
}
总结:actions和mutations是在methods选项中映射的,state和getters是在computed选项中映射的。
四、vuex的模块化
随着项目的规模越来越大,状态机的功能越来越多的时候,我们仅仅将所有的功能写在store/index.js中,这样会带来如下的麻烦
-
业务结构不够清晰
-
可读性很差
-
可维护性很差
1、模块的实现步骤
-
在src/store文件夹下创建modules文件夹
-
在modules文件下创建shopcart.js,内容如下
特别注意:如果要模块化,必须要在该对象中设置
namespaced:true
export default {namespaced:true,state: {shopcartList: []},mutations: {getShopcartList_Sync(state, payload) {console.log('------2、store中的mutations的getShopcartList_Sync--------------');console.log('payload', payload);state.shopcartList = payload}},actions: {async getShopcartList_Async(context) {console.log('------1、store中的actions的getShopcartListAsync--------------');let result = await Vue.prototype.$api.shopcart.getShopcartData()context.commit('getShopcartList_Sync', result.data)},async checkedProduct_Async(context, payload) {console.log('------1、store中的actions的checkedProduct_Async--------------', payload);let result = await Vue.prototype.$api.shopcart.checkProducts(payload)if (result.code) {//在actions中方法调用actions中的方法context.dispatch('getShopcartList_Async')}},async changeNum_Async(context, payload) {console.log('------1、store中的actions的changeNum_Async--------------', payload);let result = await Vue.prototype.$api.shopcart.changeNum(payload)if (result.code) {context.dispatch('getShopcartList_Async')}}},getters: {totalPrice: state => state.shopcartList.filter(item => item.checked).reduce((prev, cur) => prev + cur.price * cur.num, 0)}
}
-
在store/index文件中引入该模块
import Vue from 'vue'
import Vuex from 'vuex'
import shopcart from './modules/shopcart'
import counter from './modules/counter'
Vue.use(Vuex)
const store=new Vuex.Store({state:{},mutations:{},actions:{},getters:{},modules:{a:shopcart,b:counter}})
//导出store
export default store
-
在组件中引用
-
原生方式引入
调用actions的方法
this.$store.dispatch("模块名/actions的相关方法名")
调用getters
{{$store.getters['模块名/getters的相关名称']}}
调用state
{{$store.state.模块名.数据名}}
调用mutations
this.$store.commit('模块名/mutations的相关方法名')
2、辅助函数访问模块化
-
辅助函数访问模块化的vuex的步骤
-
导入createNamespacedHelpers
import {createNamespacedHelpers} from 'vuex'
-
通过createNamespacedHelpers()来获取辅助函数
const {mapActions,mapState,mapGetters}=createNamespacedHelpers('模块名')
注意:如果在一个组件中要映射多个模块的辅助函数,就需要为每个模块的辅助函数取别名,解决命名冲突
const {mapActions:别名,mapState:别名,mapGetters:别名}=createNamespacedHelpers(模块名)
-
在computed或者methods选项中通过扩展运算符实现映射
methods:{...mapShopcartActions(["getShopcartList_Async"]),...mapCounterMutations(["increment_Sync"]),},computed:{...mapShopcartState(["shopcartList"]),...mapShopcartGetters(["totalPrice"]),...mapCounterState(["num"])}
五、vuex的持久化
vuex中的数据,一旦页面刷新之后会丢失?怎么处理?【回答】
由于vuex状态机中的数据是瞬时的, 保存在内存中的,所以页面刷新后,数据会丢失,如果要解决这个问题,需要将状态机中的数据进行持久化
不是所有的状态机的数据都需要持久化的
持久化的思路:持久化就是将vuex状态机中的数据保存在localStorage中存一份
1、使用vuex-persistedstate
插件来实现vuex持久化
使用的步骤如下所示
-
安装
vuex-persistedstate
依赖包
npm i vuex-persistedstate
-
在src/store/index.js中导入
vue-persistedstate
import createPersistedstate from 'vuex-persistedstate'
-
在src/store/index.js在仓库入口文件中配置插件
const store=new Vuex.Store({//....省略plugins:[createPersistedstate({//存在localstorage中的名字key:'store-num-key',//模块名.数据名paths:['b.num']})]
})
相关文章:

VUE笔记(九)vuex
一、vuex的简介 1、回顾组件之间的通讯 父组件向子组件通讯:通过props实现 子组件向父组件通讯:通过自定义事件($emit)方式来实现 兄弟组件之间的通讯:事件总线($eventBus)、订阅与发布方式来实现 跨级组件的通讯…...
Webpack高频面试题
Webpack高频面试题 1 谈谈你对webpack的看法 现在的前端网页功能丰富,特别是SPA(single page web application 单页应用)技术流行后,JavaScript的复杂度增加和需要一大堆依赖包,还需要解决Scss,Less……新…...

数字基带传输系统
文章目录 前言一、数字基带系统基本组成二、基本码型1、数字基带信号2、6 种基本码型 三、数字基带信号的频谱特性四、数字基带信号选码1、原则2、常用的传输码型①、AMI 码(传号交替反转码)②、 H D B 3 HDB_3 HDB3 码(3 阶高密度双极性码…...

FPGA使用MIG调用SODIMM内存条接口教程,提供vivado工程源码和技术支持
目录 1、前言免责声明 2、SODIMM内存条简介3、设计思路框架视频输入视频缓存MIG配置调用SODIMM内存条VGA时序视频输出 4、vivado工程详解5、上板调试验证6、福利:工程代码的获取 1、前言 FPGA应用中,数据缓存是一大重点,不管是图像处理还是A…...
深度学习数据预处理
参考文章:深度学习中的数据预处理方法总结 在深度学习中,数据预处理(preprocessing)的重要性体现在以下几个方面: 1、数据质量: 原始数据通常包含错误、缺失值、异常值和噪声。预处理能够检测和处理这些问…...

[C++] STL_vector 迭代器失效问题
文章目录 1、前言2、情况一:底层空间改变的操作3、情况二:指定位置元素的删除操作4、g编译器对迭代器失效检测4.1 扩容4.2 erase删除任意位置(非尾删)4.3 erase尾删 5、总结 1、前言 **迭代器的主要作用就是让算法能够不用关心底…...

C语言暑假刷题冲刺篇——day5
目录 一、选择题 二、编程题 🎈个人主页:库库的里昂 🎐CSDN新晋作者 🎉欢迎 👍点赞✍评论⭐收藏✨收录专栏:C语言每日一练✨相关专栏:代码小游戏、C语言初阶、C语言进阶🤝希望作者…...

若依Cloud集成Flowable6.7.2
项目简介 基于若依Cloud的Jove-Fast微服务项目,集成工作流flowable(接上篇文章) 若依Cloud集成积木报表 项目地址:https://gitee.com/wxjstudy/jove-fast 后端 新建模块 目录结构如下: 引入依赖 前提:引入依赖之前先配置好maven的setting.xml &…...

动态不确定性的动态S过程(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

LoadRunner操作教程
日升时奋斗,日落时自省 目录 1、Virtual User Generator (VUG) 1.1、WebTours系统 1.1.1、WebTours启动 1.1.2、WebTours配置 1.2、脚本录制 1.3、编译 1.4、脚本运行 1.5、加强脚本 1.5.1、事务插入 1.5.2、插入集合点 1.5.3、参…...

.NET Core 实现日志打印输出在控制台应用程序中
在本文中,我们将探讨如何在 .NET Core 应用程序中将日志消息输出到控制台,从而更好地了解应用程序的运行状况。 .NET Core 实现日志打印输出在控制台应用程序中 在 .NET Core 中,日志输出打印是使用 Microsoft.Extensions.Logging 命名空间…...

Nginx正向代理与反向代理及Minio反向代理实操(三)
本文是对: Nginx安装及Minio集群反向动态代理配置(二) 文的进一步完善: 多台服务器间免密登录|免密拷贝 Cenos7 搭建Minio集群部署服务器(一) Cenos7 搭建Minio集群Nginx统一访问入口|反向动态代理(二) Spring Boot 与Minio整合实现文件上传与下载(三) CentOS7的journa…...

Xmake v2.8.2 发布,官方包仓库数量突破 1k
Xmake 是一个基于 Lua 的轻量级跨平台构建工具。 它非常的轻量,没有任何依赖,因为它内置了 Lua 运行时。 它使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好&#x…...

加油站抽烟烟火智能识别算法
加油站抽烟烟火智能识别系统通过yoloopencv网络模型图像识别分析技术,加油站抽烟烟火智能识别算法识别出抽烟和燃放烟火的情况,并发出预警信号以提醒相关人员,减少火灾风险。OpenCV基于C实现,同时提供python, Ruby, Matlab等语言的…...
web前端开发中的响应式布局设计是什么意思?
响应式布局是指网页设计和开发中的一种技术方法,旨在使网页能够在不同大小的屏幕和设备上都能良好地显示和交互。这种方法使得网页可以自动适应不同的屏幕尺寸,包括桌面电脑、平板电脑和手机等。 在Web前端开发中,响应式布局通常使用CSS&…...

【LeetCode-面试经典150题-day14】
目录 19.删除链表的倒数第N个结点 82.删除排序链表中的重复元素Ⅱ 61. 旋转链表 86.分隔链表 146.LRU缓存 19.删除链表的倒数第N个结点 题意: 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 【输入样例】head [1,2,3,4,5…...
【算法系列总结之分组循环篇】
【算法系列总结之分组循环篇】 分组循环1446.连续字符1869.哪种连续子字符串更长1957.删除字符使字符串变好2038.如果相邻两个颜色均相同则删除当前颜色1759.统计同质子字符串的数目2110.股票平滑下跌阶段的数目1578.使绳子变成彩色的最短时间1839.所有元音按顺序排布的最长子字…...

汽车摩托车零部件出口管理ERP解决方案
近年来,随着全球经济的发展,人们对交通工具的需求增加,国内汽车、摩托车市场的不断扩大,以及国内制造技术的不断提高,中国汽车、摩托车零部件出口业务迎来了广阔的发展前景,带动了汽车配件和摩托车配件市场…...

NPM 管理组织包
目录 1、关于组织范围和包 1.1 管理无作用域的包 2、使用组织设置配置npm客户端 2.1 配置您的npm客户端以使用您组织的范围 为所有新包设置组织范围 为单个包设置组织范围 2.2 将默认包可见性更改为public 将单个包的包可见性设置为public 将所有包的包可见性设置为pu…...
蓝桥杯上岸每日N题 (修剪灌木)
大家好 我是寸铁 希望这篇题解对你有用,麻烦动动手指点个赞或关注,感谢您的关注 不清楚蓝桥杯考什么的点点下方👇 考点秘籍 想背纯享模版的伙伴们点点下方👇 蓝桥杯省一你一定不能错过的模板大全(第一期) 蓝桥杯省一你一定不…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...