Vue2项目中vuex如何简化程序代码,提升代码质量和开发效率

        Vuex为Vue中提供了集中式存储 + 库,其主要分为state、getter、mutation、action四个模块,它们每个担任了不同角色,分工不同;Vuex允许所有的组件共享状态抽取出来,以一个全局单例模式管理,状态集中存储在同一个地方,并且以相同的方式访问和修改。

        这样使得组件间的通信变的简单,组件之间不需要直接通信,只需要从Vuex的store中获取它们需要的数据即可。

        虽然Vuex在Vue中担任重要的角色,通过可预测化的状态管理模式来帮助开发者更好地管理复杂应用的状态。但是当遇到某些模块业务属性较多情况下,定义和管理也是相当繁琐,尤其是对其命名和调用,所以此时则需要通过有效地简化程序代码,来减少不必要的冗余,提升代码的整体质量。

一、Vuex的使用

        在Vue2中,关于vuex的安装和使用已写过一篇,有不了解可以前去查看,地址:Vue.js快速入门之二:使用状态管理工具Vuex_控制台输出vuex的数据-CSDN博客

        在这里,我们使用在store/index.js中定义userInfo和accessToken状态,代码如下:

import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex);export default new Vuex.Store({// 定义属性state: {userInfo: '',accessToken: ''},// 定义计算属性getters: {user_info(state){return state.userInfo},access_token(state){return state.accessToken}},// 定义业务处理函数actions: {userInfoChange({commit}, value) {commit('USER_INFO_CHANGE', value)},accessTokenChange({commit}, value) {commit('ACCESS_TOKEN_CHANGE', value)}},// 定义属性裂变方法mutations: {USER_INFO_CHANGE(state, value) {state.userInfo = value},ACCESS_TOKEN_CHANGE(state, value){state.accessToken = value}}
});

       此时Vuex中则会出现这两个属性了,如下图:

二、较复杂业务状态管理

        对于比较常规的、属性较少的,且全局统一使用的可以定义在根节点,但对于某些特定业务或属性较多的,则需要单独定义一个子状态树去管理。

        在store目录中创建modules文件夹,用于创建和定义子模块业务的状态管理器。

        例如,商城App中,除了商品列表可以下单外,首页中精品推荐、热销商品等等商品展示位也可以点击下单。这样支付需要的信息,可以统一放到一个特定业务状态管理器中,做到集中管理。

        首先,创建modules/order.js用于处理订单业务模块。代码如下:

/*** 定义订单业务模块*/
export default {state: {goodsName: '',    // 商品名称goodsPrice: 0,    // 商品价格goodsNumber: 0,   // 商品选择数量couponList: [],   // 使用 优惠券 列表freight: 0,       // 运费originPrice: 0,   // 原价格},getters: {goods_name(state) {return state.goodsName},goods_price(state) {return state.goodsPrice},goods_number(state) {return state.goodsNumber},coupon_list(state) {return state.couponList},// 优惠券价格之和coupon_use_price(state){return state.couponList.reduce((total, item) => total + item.price, 0)},coupon_number(state) {return state.couponList.length},freight_price(state) {return state.freight},origin_price(state) {return state.originPrice},// 计算支付价格pay_price(state) {return state.goodsPrice * state.goodsNumber + state.freight},// 计算应付金额total_price(state, getter) {return getter.pay_price - getter.coupon_use_price},// 节约成本cost_saving(state, getter) {return (state.originPrice * state.goodsNumber - getter.total_price).toFixed(1)}},actions: {// 更新属性参数orderInfoChange({commit}, params) {if('undefined' !== typeof params['goodsName']) commit('GOODS_NAME', params.goodsName)if('number' === typeof params['goodsPrice']) commit('GOODS_PRICE', params.goodsPrice)if('number' === typeof params['goodsNumber']) commit('GOODS_NUMBER', params.goodsNumber)if(params['couponList']&&Array.isArray(params['couponList'])) commit('COUPON_LIST', params.couponList)if('number' === typeof params['freight']) commit('FREIGHT', params.freight)if('number' === typeof params['originPrice']) commit('ORIGIN_PRICE', params.originPrice)}},mutations: {GOODS_NAME(state, value) {state.goodsName = value},GOODS_PRICE(state, value) {state.goodsPrice = value},GOODS_NUMBER(state, value) {state.goodsNumber = value},COUPON_LIST(state, value) {state.couponList = value},FREIGHT(state, value) {state.freight = value},ORIGIN_PRICE(state, value) {state.originPrice = value}}
}

        此时,vuex中状态树如下图:

        此时我们在页面中调用orderInfoChange业务方法,为状态管理器中添加点数据,再看看效果,代码如下:

<script>
export default {name: 'App',data(){return {}},created() {this.$store.dispatch('orderInfoChange', {goodsName: '红薯粉丝500g',    // 商品名称goodsPrice: 29.0,             // 商品价格goodsNumber: 10,              // 商品选择数量couponList: [{name: "券1", price: 0.5},{name: "券2", price: 1.2}],freight: 20,                  // 运费originPrice: 32.5,            // 原价格})}
}
</script>

        如下图,只管将订单原始数据传入,通过Vuex对数据统一管理和集中业务处理,由Vuex完成数据计算、修改和输出,而不必在每个业务中单独计算,从而保证结果的一致性。

        在下单页面,直接取getters中的计算属性即可,当state中属性值改造后,其值也会实时更新为最新数据和数据合成结果。

三、精简模块内属性定义

        如上下单业务,是方便了各业务模块中,商品下单信息的统一管理和业务数据处理;但是对于四大模块中定义如此多属性和方法,随着项目中功能升级和信息增加,定义属性和方法越来越多,对后期管理和维护的工作量也是比较大的。

        对于此处,个人对Vuex有一些见解,通过程序自动完成部分属性和方法的定义,来简化流程。状态管理中,getters和actions的计算属性和业务层较多,而state和mutations则比较单一,所以这里将利用state,通过函数方法自动完成相关属性和函数的定义,再将其结果还原到状态树中。

 第一步:在utils/utils.js文件中定义useStateAndMutations()函数,用于重构状态树中需要的属性和方法。代码如下:

/*** 驼峰转下划线*/
const camelCaseToSnakeCase = str => {return str.replace(/\B(?=[A-Z])/g, '_')
}/*** 构建state与mutations,以commit执行类型常量*/
export const useStateAndMutations = (CONST_PARAMS) => {// 重构数据const list = Object.keys(CONST_PARAMS).map(item => {return {origin: item,                                     // 原始值upper: camelCaseToSnakeCase(item).toUpperCase(),  // 下划线 - 大写snake: camelCaseToSnakeCase(item).toLowerCase()   // 下划线 - 小写}})// mutationTypes 常量定义const mutationTypes = list.reduce((obj, item) => Object.assign(obj, { [item.upper]: item.origin }),{});// getters 计算属性定义(如果直接使用state数据,则此部分可以忽略)const getters = list.reduce((obj, item) => Object.assign(obj, { [item.snake](state){ return state[item.origin] } }),{})// mutations 定义const mutations = list.reduce((obj, item) => Object.assign(obj, { [item.origin](state, value){ state[item.origin] = value } }),{})// 对外暴露 生产出来的数据return { mutationTypes, getters, mutations }
}

第二步:将@/utils/utils.js引入到order.js文件中,然后通过useStateAndMutations()解构出mutationTypes, getters, mutations,并将getters和mutations还原到状态树中。代码如下:

import { useStateAndMutations } from '@/utils/utils'
// 定义state属性
const useState = {goodsName: '',    // 商品名称goodsPrice: 0,    // 商品价格goodsNumber: 0,   // 商品选择数量couponList: [],   // 使用 优惠券 列表freightPrice: 0,  // 运费originPrice: 0,   // 原价格
}
// 执行构建函数
const { mutationTypes, getters, mutations } = useStateAndMutations(useState)/*** 定义订单业务模块*/
export default {state: useState,getters: {...getters,// 优惠券价格之和coupon_use_price(state){return state[mutationTypes.COUPON_LIST].reduce((total, item) => total + item.price, 0)},coupon_number(state) {return state[mutationTypes.COUPON_LIST].length},// 计算支付价格pay_price(state) {return state[mutationTypes.GOODS_PRICE] * state[mutationTypes.GOODS_NUMBER] + state[mutationTypes.FREIGHT_PRICE]},// 计算应付金额total_price(state, getter) {return getter.pay_price - getter.coupon_use_price},// 节约成本cost_saving(state, getter) {return (state[mutationTypes.ORIGIN_PRICE] * state[mutationTypes.GOODS_NUMBER] - getter.total_price).toFixed(1)}},actions: {// 更新属性参数orderInfoChange({commit}, params) {if('undefined' !== typeof params[mutationTypes.GOODS_NAME]) commit(mutationTypes.GOODS_NAME, params[mutationTypes.GOODS_NAME])if('number' === typeof params[mutationTypes.GOODS_PRICE]) commit(mutationTypes.GOODS_PRICE, params[mutationTypes.GOODS_PRICE])if('number' === typeof params[mutationTypes.GOODS_NUMBER]) commit(mutationTypes.GOODS_NUMBER, params[mutationTypes.GOODS_NUMBER])if(params[mutationTypes.COUPON_LIST]&&Array.isArray(params[mutationTypes.COUPON_LIST])) commit(mutationTypes.COUPON_LIST, params[mutationTypes.COUPON_LIST])if('number' === typeof params[mutationTypes.FREIGHT_PRICE]) commit(mutationTypes.FREIGHT_PRICE, params[mutationTypes.FREIGHT_PRICE])if('number' === typeof params[mutationTypes.ORIGIN_PRICE]) commit(mutationTypes.ORIGIN_PRICE, params[mutationTypes.ORIGIN_PRICE])}},mutations
}

        此时再看order.js文件中代码,已经明显减少了很多代码,最终Vuex状态管理器中属性结构还是和之前一样,如下图:

        输出mutationTypes, getters, mutations三个结果,大家可能会比较好理解useStateAndMutations()方法到底做了什么,如下图:

        通过useStateAndMutations()方法,只需两步操作,就将本该手动定义的常量、计算属性和修改属性值(裂变)方法,用state属性中的key值来完成,从而简化操作。

四、orderInfoChange优化

        在orderInfoChange方法中,大家可能看的眼花缭乱,但可以看出都是通过mutationTypes常量值来取值的,所以通过以下代码,对代码进行分类处理和优化,从而简化并能更好理解。

actions: {// 更新属性参数orderInfoChange({commit}, params) {if('undefined' === typeof params) return;// 字符串数据处理[mutationTypes['GOODS_NAME']].forEach(key => {if('string' === typeof params[key]) commit(key, params[key])});// number数据处理[mutationTypes.GOODS_PRICE, mutationTypes.GOODS_NUMBER, mutationTypes.FREIGHT_PRICE, mutationTypes.ORIGIN_PRICE].forEach(key => {if('number' === typeof params[key]) commit(key, params[key])});// 数组数据处理[mutationTypes.COUPON_LIST].forEach(key => {if(params[key]&&Array.isArray(params[key])) commit(key, params[key])});}
}

        进行调整后,商品信息传入orderInfoChange中后,数据依然正常赋值及裂变,如下图:

        综上所述,我们在JavaScript开发中,可以简化程序代码和减少不必要的冗余代码,来提高代码质量、可维护性和可读性。函数式编程中,利用高阶函数(如map、filter、reduce等数组方法)和纯函数来简化对数组和集合的操作;编写可复用的函数,避免重复代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1548049.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

AniJS:无需编程的动画解决方案

前言 在网页设计中&#xff0c;动画效果能够显著提升用户体验&#xff0c;但传统的动画实现往往需要复杂的 JavaScript 代码。 AniJS 库的出现&#xff0c;为设计师和开发者带来了一种全新的动画实现方式&#xff0c;它通过简单的 HTML 属性就能创建出令人惊叹的动画效果。 介…

文档解析与向量化技术加速 RAG 应用落地

在不久前举办的 AICon 全球人工智能开发与应用大会上&#xff0c;合合信息智能创新事业部研发总监&#xff0c;复旦博士常扬从 RAG 应用落地时常见问题与需求&#xff08;文档解析、检索精度&#xff09;出发&#xff0c;分享了针对性的高精度、高泛化性、多版面多元素识别支持…

LeetCode[中等] 138. 随机链表的复制

给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成&#xff0c;其中每个新节点的值都设为其对应的原节点的值。新节点的 n…

贴片式TF卡(SD NAND)参考设计

【MK 方德】贴片 TF 卡参考设计 一、电路设计 1、 参考电路&#xff1a; R1~R5 (10K-100 kΩ)是上拉电阻&#xff0c;当 SD NAND 处于高阻抗模式时&#xff0c;保护 CMD 和 DAT 线免受总线浮动。 即使主机使用 SD NAND SD 模式下的 1 位模式&#xff0c;主机也应通过上拉电阻…

SpringBoot 流式输出时,正常输出后为何突然报错?

一个 SpringBoot 项目同时使用了 Tomcat 的过滤器和 Spring 的拦截器&#xff0c;一些线程变量在过滤器中初始化并在拦截器中使用。 该项目需要调用大语言模型进行流式输出。 项目中&#xff0c;笔者使用 SpringBoot 的 ResponseEntity<StreamingResponseBody> 将流式输…

照片压缩方法分享,掌握这些小技巧轻松压缩

照片已成为我们记录生活、分享美好的重要方式。然而&#xff0c;随着手机像素的不断提升&#xff0c;照片文件体积也越来越大&#xff0c;给存储和传输带来了不小的挑战。今天&#xff0c;就为大家介绍几种高效的照片压缩方法&#xff0c;掌握这些方法就能够轻易对图片进行压缩…

寻找右区间

题目链接 寻找右区间 题目描述 注意点 -10^6 < starti < endi < 10^6每个间隔的起点都 不相同如果某个区间 i 不存在对应的 右侧区间 &#xff0c;则下标 i 处的值设为 -1 解答思路 因为本题需要找到每个interval大于interval对应end的最小start值&#xff0c;所…

vue-i18n在使用$t时提示类型错误

1. 问题描述 Vue3项目中&#xff0c;使用vue-i18n&#xff0c;在模版中使用$t时&#xff0c;页面可以正常渲染&#xff0c;但是类型报错。 相关依赖版本如下&#xff1a; "dependencies": {"vue": "^3.4.29","vue-i18n": "^9.1…

红绿灯倒计时读秒数字识别系统源码分享

红绿灯倒计时读秒数字识别检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of …

小程序开发平台源码系统 各行各业适用的小程序开的平台 带完整的安装代码包以及搭建部署教程

系统概述 本系统采用模块化设计&#xff0c;包含前端展示层、后端逻辑处理层、数据库存储层以及管理后台等多个核心组件。前端展示层负责小程序的界面设计与交互体验&#xff1b;后端逻辑处理层则负责数据处理、业务逻辑实现及与第三方服务的对接&#xff1b;数据库存储层用于…

符合二级等保要求的SSL证书

根据等级保护对象在国家安全、经济建设、社会生活中的重要程度&#xff0c;以及一旦遭到破坏、丧失功能或者数据被篡改、泄露、丢失、损毁后&#xff0c;对国家安全、社会秩序、公共利益以及公民&#xff0c;法人和其他组织的合法权益的侵害程度等因素&#xff0c;等级保护对象…

第1章 C++初识

1.1 编写第一个C程序 1.打开Visual Studio点击"创建新项目" 2.点击"空项目"&#xff0c;并点击"下一步" 3.设置"项目名称"并"设置地址" 4.打开项目后&#xff0c;右击"源文件"并选择"添加"的"新建…

低代码可视化开发-uniapp新闻跑马灯组件-代码生成器

新闻跑马灯效果组件是一种在新闻、数据可视化大屏或其他信息展示场景中常用的动态文本展示方式。它通过滚动文本的形式&#xff0c;在有限的空间内展示更多的信息内容&#xff0c;同时增加了视觉吸引力和动态感。以下是对新闻跑马灯效果组件的详细介绍&#xff1a; 一、定义与…

LVGL-触摸屏-实体按键-编码器-多功能按键)

在使用stm32移植lvgl时由于没有触摸屏&#xff0c;所以选择了编码器和按键作为输入设备。但是按照教程全部正确的设置了编码器和按键后&#xff0c;编码器的回调函数不能被调用即encoder_read();函数中的内容不能被调用。debug后发现是创建输入设备时的indev_drv被覆盖&#xf…

​ETHShanghai 2024:十月盛典,首批嘉宾重磅揭晓!

随着「ETHShanghai 2024」的筹备工作不断推进&#xff0c;已经邀请了多位重要嘉宾参与。同时&#xff0c;以太坊联合创始人Vitalik Buterin 也将通过线上形式参与并进行开幕致辞。 目前&#xff0c;已经确认出席的嘉宾还包括 Mask Network 创始人 Suji Yan、EthStorage 创始人…

eCharts扩展图表

地址&#xff1a;echarts图表集 示例截图&#xff1a;

【Redis】下载安装Redis和Redis图形化界面工具教程(2024最新版本,史上最详细)

目录 一、Redis简介 二、Redis下载和安装 2.1、下载 2.2、安装 2.3、环境变量配置&#xff08;可省略&#xff09; 三、Redis启动验证 3.1、点击键盘上的WinR键&#xff0c;在跳出的运行界面中输入cmd并确定 3.2、输入redis-cli -v 查看redis的版本号 3.3、接着我们再…

python爬虫案例——抓取三级跳转网页,实现逐页抓取,数据存入mysql数据库(10)

文章目录 1、目标任务2、网页分析3、完整代码1、目标任务 目标站点:情话网(http://www.ainicr.cn/tab/) 任务:抓取该网站下所有标签下的所有情话语句,并将其存入mysql数据库 2、网页分析 用浏览器打开网页,按F12或右键检查,进入开发者模式,在Network-Doc下找到网页的数…

Thingsboard规则链:Related Device Attributes节点详解

引言 在物联网&#xff08;IoT&#xff09;领域&#xff0c;Thingsboard作为一款强大的物联网平台&#xff0c;其规则链功能为企业提供了高度定制化的数据处理和自动化控制方案。其中&#xff0c;Related Device Attributes节点是一个特别实用的组件&#xff0c;它能够访问和操…

【专题】新能源发电行业及其市场化进程概览白皮书报告合集PDF分享(附原数据表)

原文链接&#xff1a;https://tecdat.cn/?p37802 随着中国经济结构的持续优化以及能源政策的不断进步&#xff0c;我国的能源消费呈现出稳定增长的态势。与此同时&#xff0c;能源利用效率逐步提高&#xff0c;清洁能源在能源结构中的比例也在稳步上升&#xff0c;这为国家的…