讲讲项目里的状态存储器vuex

news2024/11/28 0:55:22

前言

        在一个企业级的应用里,状态存储器起着举足轻重的作用。与我们日常的练手项目不同,企业级项目的vuex更专注更集中更便捷。

简单回顾

        让我们简单回顾一下vuex这个插件的用法。

   Vuex 的状态存储是响应式的。

         当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

   只能通过mutation改变vuex里面的store。不能直接改变store里面的状态

 mutations: {
    setViewList(state, list) {
      state.viewList = list;
    }
}

        集中化、显式化地修改stroe里的状态,方便管理方便阅读。

  最简单的例子

import { createApp } from 'vue'
import { createStore } from 'vuex'

// 创建一个新的 store 实例
const store = createStore({
  state () {
    return {
      count: 0
    }
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})

const app = createApp({ /* 根组件 */ })

// 将 store 实例作为插件安装
app.use(store)

         vue组件里:

methods: {
  update() {
    // 修改
    this.$store.commit('increment')
    // 查看
    console.log(this.$store.state.count)
  }
}

项目里的应用

        我们在项目的src文件夹里创建一个store专门用来放置状态管理相关的逻辑

        

 index.js:

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

        index是整个状态管理的入口文件,Vue.use(Vuex)会在创建vue实例之前执行。Vue.use的作用想必大家都很清楚了:安装 Vue.js 插件,如果传入的是一个对象,则会执行它的install方法。如果传入的是一个函数,那么他将执行这个函数。

        举个例子:

// plugin.js  ————src\plugin\plugin.js
export const plugin = {
  install() {
    alert("我是install内的代码")
  },
}
 
// main.js中引入自定义插件
import Vue from "vue"
import {Plugin} from './plugin/plugin.js'
Vue.use(plugin) // 页面显示"我是install内的代码"

        当然啦,index.js会被Vue实例调用

import store from './store';
import router from './router';
import App from './App.vue';

// 初始化Vue
  new Vue({
    router,
    store,
    render: h => h(App),
}).$mount('#app');

       缕清了最基本的引用思路,我们再回头来仔细琢磨里面的门道。

store/index.js

        这个文件是需要抛出一个vuex实例给vue用的。

export default new Vuex.Store({
    ...
})

        这里面仓库和方法等属性都是空的

new Vuex.Store({
  state: {},
  mutations: {},
  actions: {},
  strict: true,
  ...
}

        因为我们要借助模块化思想来书写这个状态管理器

import global from './modules/global';
import form from './modules/form';
import formDesign from './modules/form-design';
...

const store = new Vuex.Store({
  state: {},
  mutations: {},
  actions: {},
  strict: true,
  modules: {
    global,
    form,
    formDesign,
    ...
  },
  ...
}

        此时这个项目结构就很简单清晰啦 ,我们来看看模块的状态管理器长啥样

        其实就是和状态管理器一样,有state有mutations ,甚至你喜欢的话,还可以往里面继续嵌套模块module。形成三级、四级、五级等等多层级的模块化状态管理器。

        细心的朋友,看到这里有个namespaced啦。如果不了解命名空间的相关知识,请看我这篇推文,否则后面可能会理解不了。

Vuex命名空间及如何获取根模块、兄弟模块状态管理器_AI3D_WebEngineer的博客-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_42274805/article/details/133269196?spm=1001.2014.3001.5502

优雅书写命名空间

       项目使用的是ts+vue。所以借助Vuex-class进行绑定(主要用于Vue2.0+TS使用store的全局变量和方法)

        使用方法:

        1.安装vuex-class

npm install --save vuex-class

          2.全局使用vuex-class的方法:

// store/index.js
export default new Vuex.Store({
  state : {
    count : -1,
  },
 
  mutations: {
   addcount(state){
      state.count++
   }
  },

  actions: {
    change({commit}){
      commit("addcount")
    }
  },
})
// page.vue

//首先引入

import {Action,State} from'vuex-class'

//直接使用装饰器就可以获取到了
@State('count') globalCount
@Action('change') changecount

//然后就是直接调用
create(){
    log(`vuex中的count数据为${this.globalCount}`)
}
add(){
    //调用一次add()就触发一次
    this.changecount()
}

        这样子确实能用,但不美观。我们结合命名空间来优雅地书写 。

        3.分模块使用

        当分模块调用state、mutations、actions、getters时,需要引入namespace,并且调用的时候需要加上@nameSpaceName

        先来看日常是怎么写的:

import common from './common'
export default new Vuex.Store({
  state:{},
  modules: {
    // here here! 
    common
  }
})
// common.js
export default {
    namespaced: true,
    state: {count:0}
    mutations: {
        ADD_COUNT(state){
            state.count++
        }
    }
}
import {Action, namespace,State} from'vuex-class'

// 获取com模块
const mymodule = namespace('common')



@Component()
export default class HomeView extends Vue {
     @mymodule.State('count') stateCount
     @mymodule.Mutation('ADD_COUNT') addCount
    
    created() {
        console.log(this.stateCount)
        this.addCount()
    }
    
}

        在项目里这么写肯定是没问题的,但是太繁琐,不工整。我们回归到项目里:

        src/store/index.js

import Vue from 'vue';
import Vuex from 'vuex';
import global from './modules/global';
import form from './modules/form';
import formDesign from './modules/form-design';
import application from './modules/application';
import formSetting from './modules/form-setting';
import formPermission from './modules/form-permission';
import formView from './modules/form-view';
import file from './modules/file';
...


Vue.use(Vuex);

const store = new Vuex.Store({
  state: {},
  mutations: {},
  actions: {},
  strict: true,
  modules: {
    global,
    form,
    formDesign,
    application,
    formSetting,
    file,
    ...
  }
});

export default store;

        紧接着,我们创建一个枚举类文件

        src/enum/store.js

import { namespace } from 'vuex-class';

export const globalModule = namespace('global');
export const formModule = namespace('form');
export const crossStorageModule = namespace('crossStorage');
export const formDesignModule = namespace('formDesign');
export const formSettingModule = namespace('formSetting');
export const applicationModule = namespace('application');
export const formPermissionModule = namespace('formPermission');
export const formViewModule = namespace('formView');
...

        这么写有什么好处?其实就是把所有的命名空间模块枚举出来。实现按需引入。

        具体项目文件:不需要再引入import {Action, namespace,State} from'vuex-class'

import { formDesignModule, applicationModule } from '@/enum/store';
...

@Component({
  components: {},
})
export default class DashboardDesignLayout extends Vue {
  ...
  @formDesignModule.State form;
  @formDesignModule.Action init;
  @formDesignModule.Mutation reset;
  @applicationModule.Action getApplicationDetail;
  @applicationModule.State applicationDetail;
  @formDesignModule.Mutation saveForm;
  @formDesignModule.Getter isFormStatistics;
  @formDesignModule.Getter isApplicationHome;
}

         注意一下。比如我们要用这个init方法。项目里应该这么写:

async handleEdit() {
    ....
    await this.init(result.pkId);
}

        vuex里应该这么写:

actions: {
    async init({ commit }, formId) {
      const form = await getFormData(formId);
      commit('saveForm', form);
    },
}

        用{commit, state,getters,dispatch}跟传参区分开来。注意传参如果有多个,最好用对象传参!

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

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

相关文章

ShardingSphere分库分表(二):基础介绍

1、简介 Apache ShardingSphere 是一套开源的分布式数据库中间件解决方案组成的生态圈,它由 JDBC、Proxy 和 Sidecar(规划中)这 3 款相互独立,却又能够混合部署配合使用的产品组成。 它们均提供标准化的数据分片、分布式事务和数…

文件包含漏洞原理刨析

文件包含漏洞 开发人员通常会把可重复使用的函数写到单个文件中,在使用某些函数时,直接调用此文件,而无需再次编写,这种调用文件的过程一般被称为包含。 为了使代码更加灵活,通常会将被包含的文件设置为变量&#xf…

flutter版本dart版本对应关系

Flutter 版本架构Ref发布日期Dart 版本3.13.5x6412fccda2023/9/213.1.23.13.5 file3.13.5arm6412fccda2023/9/213.1.23.13.5 file3.13.4x64367f9ea2023/9/143.1.23.13.4 file3.13.4arm64367f9ea2023/9/143.1.23.13.4 file3.13.3arm64b0daa732023/9/143.1.13.13.3 file3.13.3x64…

希望杯、希望数学系列竞赛辨析和希望数学超1G的真题和学习资源

中国的中小学数学竞赛种类非常多,但是说到全国性的数学竞赛,影响力最大的之一就是“希望杯”,在2017年国家喊停学科竞赛后,“希望杯”逐步停止了,但是鉴于希望杯的巨大影响力,以及背后的利益纠葛&#xff0…

【网络安全】一篇文章带你了解CTF那些事儿

文章目录 一、什么是CTF?二、CTF需要学习那些知识?新书推荐适合新手自学的网络安全基础技能“蓝宝书”:《CTF那些事儿》内容简介读者对象专家推荐目录 一、什么是CTF? CTF(Capture The Flag)中文一般译作夺…

BinDiff:二进制文件的开源比较工具

BinDiff 是一个二进制文件比较工具,可以快速查找反汇编代码中的差异和相似之处,它已开源。 使用 BinDiff,您可以识别并隔离供应商提供的补丁中漏洞的修复。 您还可以在同一二进制文件的多个版本的反汇编之间移植符号和注释,或使…

ORACLE 内存结构之系统全局区(SGA)

每个 Oracle 数据库实例都会在内存中分配一个很大的内存结构, 称为系统全局区(System Global Area), 这是一个大型的共享内存结构,每个Oracle进程都会访问它。 在Linux/Unix操作系统上,SGA是一个物理实体,使用操作系统命令能“看到它”。 它被操作系…

计算机类软件方向适合参加的比赛

前言 博主是一名计算机专业的大三学生,在校时候参加了很多比赛和训练营,现在给大家博主参加过的几个的比赛,希望能给大一大二的学生提供一点建议。 正文 最近也有比赛的,我会从时间线上来给大家推荐一些比赛,并且给…

NLP中token总结

Token 可以被理解为文本中的最小单位。在英文中,一个 token 可以是一个单词,也可以是一个标点符号。在中文中,通常以字或词作为 token。ChatGPT 将输入文本拆分成一个个 token,使模型能够对其进行处理和理解 在自然语言处理&#…

virtualbox安装linux虚拟机访问互联网(外网)的方法

virtualbox安装linux虚拟机访问互联网(外网)的方法 设置方法效果图 设置方法 效果图

【C++11】万能引用与完美转发

文章目录 1. 模板中的&&—万能引用2. 完美转发及其应用场景3. 用到的代码3.1 string.h3.2 list.h3.3 test.cpp 1. 模板中的&&—万能引用 首先我们来看这样一段代码: 这里有4个函数,我们很容易能看出来它们是一个重载的关系 然后我们给这…

Windows下libmodbus 支持upd库的编译与Qt里的调用

一. libmodbus 支持udp版库下载 https://github.com/systemmonkey42/libmodbus/tree/udp_support 二. MSYS2编译工具安装 (1)下载MSYS2并安装 下载地址:https://www.msys2.org/ 双击该exe,安装msys2 (2) 安装编译所需库 在软件安…

js惰性函数 ----如何让函数执行之后只执行函数某一部分

看下面这份ts代码 实现的效果也很简单,就是将一份文本,复制到剪切板上,未了兼容更多的浏览器(没错说的就是你>ie !),做了一个兼容性判断, 当浏览器支持navigator.clipboard这个api时,就直接调用这个api将文本复制到剪切板中, 如果不支持这个api的话,就执行else里面的代码,这…

微信小程序 request合法域名 中设置WebSocket的wss/ws报错 该域名协议头非法 问题解决

微信小程序并不支持直接用wss://格式去设置域名 但其实我们可以用缓兵之计 这里 我们直接改成 https的 然后 我们照常通过 wss://ws-api.turingapi.com/api/v2去链接 可以看到 他这里依旧连接成功了

Spring MVC 之 Restful 风格请求⽀持

Tips: REST⻛格请求是什么样的?SpringMVC对REST⻛格请求到底提供了怎样的⽀持 在 Web 系统中,前端通过 HTTP 请求给后端传递参数有四种方式,可以将参数放在请求路径、Query 参数、HTTP 协议头、HTTP 协议体中。而放在协议体中的…

五,修改.hdr插件

由于辐照度贴图是.hdr格式, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, data); osg的.hdr插件需要修改,否则格式不对。 即在ReaderWriterHDR::readImage()中修改, bool convertToRGB8 true;int pixel…

【iOS逆向与安全】DTRpcClient 抓包和代码分析记录

frida-trace -UF -m "-[DTRpcConfig isAMRPC]"onEnter(log, args, state) {log(-[DTRpcConfig isAMRPC] ~~~~~);var customObj new ObjC.Object(args[0]); // 自定义对象// 打印该对象所有属性var ivarList customObj.$ivars;for (key in ivarList) {log(key${key…

【SpringBoot】| SpringBoot集成Dubbo

目录 一:SpringBoot集成Dubbo 1. 创建公共项目 2. 创建提供者项目provider 3. 创建消费者consumer项目 4. 注册中心Zookeeper的安装 图书推荐:《Python 自动化办公应用大全》 一:SpringBoot集成Dubbo 阿里巴巴提供了 dubbo 集成 spring…

原来,这就是现货黄金投资最大的悲哀

在现货黄金投资之中,最大的悲哀是什么呢?首先要知道的是现货黄金投资中最大的悲哀并不是亏损,比如投资者会问我都亏损了,为什么不是最大的悲?哎,不就是因为想进行现货黄金投资,就是想获利的吗&a…

北斗导航系统为渔船保驾护航,助力海洋渔业发展

在无垠的海洋中,渔船扮演着举足轻重的角色,为人们带来美味的海鲜。然而,每一次渔船出海都充满了未知和危险,船只的安全成为了渔民和国家关注的焦点。幸运的是,北斗导航系统作为一项顶级技术正在为渔船保驾护航&#xf…