vue-vuex详解

news2025/1/23 2:18:30

​🌈个人主页:前端青山
🔥系列专栏:Vue篇
🔖人终将被年少不可得之物困其一生

依旧青山,本期给大家带来vue篇专栏内容:vue-vuex详解

目录

Vuex

1.vuex是什么?

2.vuex核心概念

3.vuex模块化

4. Vuex中action和mutation的区别

4.1Vuex 和 localStorage 的区别

4.2Vuex有哪几种属性?

4.3Vuex和单纯的全局对象有什么区别?

4.4为什么 Vuex 的 mutation 中不能做异步操作?

4.5 Vuex的严格模式是什么,有什么作用,如何开启?

4.6如何在组件中批量使用Vuex的getter属性

4.7 如何在组件中重复使用Vuex的mutation

5.实战应用代码

Vuex

1.vuex是什么?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 ( state )。

其具有以下优势:

  • 能够在vuex中集中管理共享的数据,便于开发和后期进行维护

  • 能够高效的实现组件之间的数据共享,提高开发效率(代码量

  • 存储在vuex中的数据是响应式的,当数据发生改变时,页面中的数据也会同步更新

什么样的数据适合存储在Vuex中?

一般情况下,只有组件之间共享的数据才有必要存储到vuex中,对于组件中私有的数据依旧存储在组件自身的data中即可。

注意事项:由于vue项目一刷新就会重新编译,因此每次刷新都会重新初始化vuex中的数据,会导致之前的数据丢失,因此vuex中一般不保存非常重要的数据。【放在vuex中的数据一般是刷新后也不影响业务的数据】

2.vuex核心概念

vuex的核心组成:

  • state:状态,用于初始化仓库中的数据,在这里声明项目中全局使用的数据

  • mutations:修改state数据的方法,存放用于修改state数据的方法

    • 只存放同于同步修改数据的方法

    • 每个方法接收俩个形参,依次是:

      • state:object,指的是仓库中的数据

      • payload:any类型,用于修改数据的数据源(可选)

    • 函数不需要return,所有操作都是基于state直接更改

  • actions:修改state数据的方法,存放用于修改state数据的方法

    • 只存放同于异步修改数据的方法

    • 每个方法接收俩个形参,依次是:

      • context:object,指的是仓库对象(上下文对象)

      • payload:any类型,用于修改数据的数据源(可选)

    • 函数不需要return,所有操作都是基于state直接更改

    • 这里的方法本身自己不直接该数据,而是通过context对象调用mutations中的方法去修改数据

  • getters:获取并修饰数据(对数据进行格式处理),存储用于修饰数据的方法

    • 里面的方法有一个形参

      • state:object,指的是仓库中的数据

    • 每个函数必须有返回值,返回修饰完的数据

  • modules:模块化,存放模块化后的仓库模块,这里存放导入进来的模块变量

vuex语法,vuex支持对象属性形式、辅助函数形式去操作store中数据,所以每个操作都具备俩个语法:

  • 获取state数据

    • 对象属性:this.$store.state.属性名

    • 辅助函数:mapState

      • 作用:将指定的state中的数据映射为组件自身的计算属性

      • 语法:

        • 写在computed中

        • ...mapState([属性名1,属性名2,....])

  • 同步修改数据

    • 对象属性:this.$store.commit(方法名,载荷数据)

    • 辅助函数:mapMutations

      • 作用:将指定的mutations中的方法映射为组件自身的方法

      • 语法:

        • 写在methods中

        • ...mapMutations([方法名1,方法名2,...])

  • 异步修改数据

    • 对象属性:this.$store.dispatch(方法名,载荷数据)

    • 辅助函数:mapActions

      • 作用:将指定的Actions中的方法映射为组件自身的方法

      • 语法:

        • 写在methods中

        • ...mapActions([方法名1,方法名2,...])

  • 获取修饰数据

    • 对象属性:this.$store.getters.属性名

    • 辅助函数:mapGetters

      • 作用:将指定的getters中的数据映射为组件自身的计算属性

      • 语法:

        • 写在computed中

        • ...mapGetters([属性名1,属性名2,....])

3.vuex模块化
  • 为什么需要模块化?

    • 团队协作开发需要

    • 方便后期维护管理

  • 怎么模块化?

    • 将除modules对象中的内容按照指定的拆分标准进行按文件分离

    • 在index.js中导入并在modules对象中注册

  • 有什么需要注意的?

    • 因为模块化,后续的语法需要有所调整,具体见下

    • 命名冲突时会执行自动合并策略

      • state,名字相同也不会冲突

      • mutations、actioms里同名方法会被合并成数组,都执行(index.js中的是最先执行的)

      • getters如果同名,无法合并,直接报错

    • 通过命名空间来避免冲突(给每个模块开启命名空间)

      • 设置模块的namespaced属性为true即可

vuex模块化后的语法:

  • 获取state数据

    • 对象属性:this.$store.state.模块名.属性名

    • 辅助函数:mapState

      • 作用:将指定的state中的数据映射为组件自身的计算属性

      • 语法:

        • 写在computed中

        • ...mapState(模块名,[属性名1,属性名2,....])

  • 同步修改数据

    • 对象属性:this.$store.commit(模块名/方法名,载荷数据)

    • 辅助函数:mapMutations

      • 作用:将指定的mutations中的方法映射为组件自身的方法

      • 语法:

        • 写在methods中

        • ...mapMutations(模块名,[方法名1,方法名2,...])

  • 异步修改数据

    • 对象属性:this.$store.dispatch(模块名/方法名,载荷数据)

    • 辅助函数:mapActions

      • 作用:将指定的Actions中的方法映射为组件自身的方法

      • 语法:

        • 写在methods中

        • ...mapActions(模块名,[方法名1,方法名2,...])

  • 获取修饰数据

    • 对象属性:this.$store.getters["模块名/属性名"]

    • 辅助函数:mapGetters

      • 作用:将指定的getters中的数据映射为组件自身的计算属性

      • 语法:

        • 写在computed中

        • ...mapGetters(模块名,[属性名1,属性名2,....])

4. Vuex中action和mutation的区别

mutation中的操作是一系列的同步函数,用于修改state中的变量的的状态。当使用vuex时需要通过commit来提交需要操作的内容。mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是实际进行状态更改的地方,并且它会接受 state 作为第一个参数:

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      state.count++      // 变更状态
    }
  }
})

当触发一个类型为 increment 的 mutation 时,需要调用此函数:

store.commit('increment')

而Action类似于mutation,不同点在于:

  • Action 可以包含任意异步操作。

  • Action 提交的是 mutation,而不是直接变更状态。

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})

Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用

context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。 所以,两者的不同点如下:

  • Mutation专注于修改State,理论上是修改State的唯一途径;Action业务代码、异步请求。

  • Mutation:必须同步执行;Action:可以异步,但不能直接操作State。

  • 在视图更新时,先触发actions,actions再触发mutation

  • mutation的参数是state,它包含store中的数据;store的参数是context,它是 state 的父级,包含 state、getters

4.1Vuex 和 localStorage 的区别

(1)最重要的区别

  • vuex存储在内存中

  • localstorage 则以文件的方式存储在本地,只能存储字符串类型的数据,存储对象需要 JSON的stringify和parse方法进行处理。 读取内存比读取硬盘速度要快

(2)应用场景

  • Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。vuex用于组件之间的传值。

  • localstorage是本地存储,是将数据存储到浏览器的方法,一般是在跨页面传递数据时使用 。

  • Vuex能做到数据的响应式,localstorage不能

(3)永久性

刷新页面时vuex存储的值会丢失,localstorage不会。

注意: 对于不变的数据确实可以用localstorage可以代替vuex,但是当两个组件共用一个数据源(对象或数组)时,如果其中一个组件改变了该数据源,希望另一个组件响应该变化时,localstorage无法做到,原因就是区别1。

4.2Vuex有哪几种属性?

有五种,分别是 State、 Getter、Mutation 、Action、 Module

  • state => 基本数据(数据源存放地)

  • getters => 从基本数据派生出来的数据

  • mutations => 提交更改数据的方法,同步

  • actions => 像一个装饰器,包裹mutations,使之可以异步。

  • modules => 模块化Vuex

4.3Vuex和单纯的全局对象有什么区别?
  • Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

  • 不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样可以方便地跟踪每一个状态的变化,从而能够实现一些工具帮助更好地了解我们的应用。

4.4为什么 Vuex 的 mutation 中不能做异步操作?
  • Vuex中所有的状态更新的唯一途径都是mutation,异步操作通过 Action 来提交 mutation实现,这样可以方便地跟踪每一个状态的变化,从而能够实现一些工具帮助更好地了解我们的应用。

  • 每个mutation执行完成后都会对应到一个新的状态变更,这样devtools就可以打个快照存下来,然后就可以实现 time-travel 了。如果mutation支持异步操作,就没有办法知道状态是何时更新的,无法很好的进行状态的追踪,给调试带来困难。

4.5 Vuex的严格模式是什么,有什么作用,如何开启?

在严格模式下,无论何时发生了状态变更且不是由mutation函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。

在Vuex.Store 构造器选项中开启,如下

const store = new Vuex.Store({
    strict:true,
})
4.6如何在组件中批量使用Vuex的getter属性

使用mapGetters辅助函数, 利用对象展开运算符将getter混入computed 对象中

import {mapGetters} from 'vuex'
export default{
    computed:{
        ...mapGetters(['total','discountTotal'])
    }
}
4.7 如何在组件中重复使用Vuex的mutation

使用mapMutations辅助函数,在组件中这么使用

import { mapMutations } from 'vuex'
methods:{
    ...mapMutations({
        setNumber:'SET_NUMBER',
    })
}

然后调用this.setNumber(10)相当调用this.$store.commit('SET_NUMBER',10)

5.实战应用代码
import { createStore } from 'vuex'
import router from '@/router'
import qs from 'qs'
​
export default createStore({
  state: {
   // token: '',
  //  menuList:[],
    hasRoutes: false,
    editableTabsValue:'/index',
    editableTabs:[
      {
        title: '首页',
        name: '/index'
      }
    ]
  },
  getters: {
    GET_TOKEN: state => {
      return sessionStorage.getItem("token")
    },
    GET_MENULIST:state => {
      return JSON.parse(sessionStorage.getItem("menuList"))
    },
    GET_PERMS:state=>{
      return JSON.parse(sessionStorage.getItem("perms"))
    },
    GET_USERINFO:state=>{
      // console.log("GET_USERINFO="+sessionStorage.getItem("userInfo"))
      return JSON.parse(sessionStorage.getItem("userInfo"))
    }
  },
  mutations: {
    SET_TOKEN: (state, token) => {
      // state.token = token
      sessionStorage.setItem("token", token)
    },
    RESET_TOKEN:(state)=>{
      //state.token=''
      sessionStorage.setItem("token", "")
    },
    SET_MENULIST:(state,menuList)=>{
      //state.menuList=menuList;
      sessionStorage.setItem("menuList", JSON.stringify(menuList))
    },
    SET_PERMS:(state,perms)=>{
      sessionStorage.setItem("perms", JSON.stringify(perms))
    },
    SET_USERINFO:(state,userInfo)=>{
      sessionStorage.setItem("userInfo", JSON.stringify(userInfo))
    },
    //动态添加tab
    ADD_TABS:(state,tab)=>{
      // debugger
      // console.log("进入条件"+state.editableTabs.findIndex(e=>e.name));
      if(state.editableTabs.findIndex(e=>e.name===tab.path)===-1){
        // if(tab.name===undefined){
        //   tab.name="操作日志"
        // }
        state.editableTabs.push({
          title: tab.name,
          name:tab.path
        });
      }
      state.editableTabsValue=tab.path
      // console.log("路由列表:"+JSON.stringify(state.editableTabs))
      // console.log("路由值:"+JSON.stringify(state.editableTabsValue))
    },
    RESET_TABS:(state)=>{
      state.editableTabsValue='/index';
      state.editableTabs=[
        {
          title: '首页',
          name: '/index'
        }
      ]
    },
    SET_ROUTES_STATE:(state,hasRoutes)=>{
      state.hasRoutes=hasRoutes
    }
  },
  actions: {
    // 安全退出
    logout(){
      window.sessionStorage.clear();
      this.state.hasRoutes=false
      router.replace('/login')
    }
  },
  modules: {
  }
})
​

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

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

相关文章

【Java 进阶篇】JQuery 动画:为页面添彩的魔法

在现代的Web开发中,用户体验的提升是至关重要的一环。而动画作为页面交互中的重要组成部分,更是为用户带来了全新的感官体验。本篇博客将深入探讨 JQuery 中动画的应用,带你进入一个充满活力的前端世界。 前言 动画是网页设计的一种重要手段…

YOLO目标检测——树叶检测数据集下载分享【含对应voc、coco和yolo三种格式标签】

实际项目应用:生物多样性研究、林业管理、环境监测和教育科研等方面数据集说明:树叶分类检测数据,真实场景的高质量图片数据,数据场景丰富,总共十个类别。标签说明:使用lableimg标注软件标注,标…

力扣刷题篇之数与位1

系列文章目录 目录 系列文章目录 前言 一、进制转换 总结 前言 本系列是个人力扣刷题汇总,本文是数与位。刷题顺序按照[力扣刷题攻略] Re:从零开始的力扣刷题生活 - 力扣(LeetCode) 一、进制转换 67. 二进制求和 - 力扣&…

(免费领源码)Java#SpringBoot#mysql高校实验室资产管理系统85189-计算机毕业设计项目选题推荐

摘 要 随着计算机技术的发展,特别是计算机网络技术与数据库技术的发展,使人们的生活与工作方式发生了很大的改观。本课题研究的高校实验室资产管理系统,主要功能模块包括后台首页,轮播图,公告管理,资源管理…

一看就会的jni,不会你来打我!

环境配置 Android Studio,这个不多说了。 简单说一下NDK的下载和环境变量,方便在Terminal里使用命令(mac版)。 下载 1.可以通过Android Studio内置的Settings-Android SDK-SDK Tools安装NDK,下载目录为 /Users/mac-xxx(Username)/Library…

服务号可以升级为订阅号吗

服务号和订阅号有什么区别?服务号转为订阅号有哪些作用?在推送频率上来看,服务号每月能推送四条消息,而订阅号可以每天(24小时)推送一条消息。如果企业开通公众号的目的是提供服务,例如售前资讯…

WPS文件丢失如何恢复?4个方法教你快速恢复!

“在WPS里保存了一些比较重要的文档,由于某些原因导致文件丢失了,这种情况下,还有办法成功恢复WPS文件吗?” WPS Office是许多用户在电脑上创建和编辑文档的首选工具。然而,有时文件会意外丢失,可能是由于误…

Linux_在命令行中以树状结构显示目录_tree

1、安装tree命令 使用tree命令,可以在命令行中以树状结构显示目录,当你想知道一个路径下文件的结构时十分方便,还有别的选项功能,下面会介绍其中的一些,完整的介绍Linux命令 - tree—LZL在线工具。 sudo apt updates…

头部厂商Q3交付量环比下滑!激光雷达,现实很骨感

由于中国自主品牌车企在高阶智驾赛道上的激进策略,全球激光雷达行业的走势,也无疑受到中国市场的影响。 本周,禾赛科技发布2023年度三季报,季度激光雷达交付量为47,440台,同比增长125.5%,其中ADAS激光雷达交…

mysql---主从复制和读写分离

主从复制 主从复制,修改,表里的数据:主mysql上的数据,新增都会同步到从mysql上面试题:mysql的主从复制的模式: 1、异步复制:mysql的默认复制就是异步复制。只要执行完之后,客户端提…

使用 Redis 构建轻量的向量数据库应用:图片搜索引擎(二)

本篇文章我们来继续聊聊轻量的向量数据库方案:Redis,如何完成整个图片搜索引擎功能。 写在前面 在上一篇文章《使用 Redis 构建轻量的向量数据库应用:图片搜索引擎(一)》中,我们聊过了构建图片搜索引擎的…

如何在10亿级别用户中检查用户名是否存在?

题目 不知道大家有没有留意过,在使用一些app注册的时候,提示你用户名已经被占用了,需要更换一个,这是如何实现的呢?你可能想这不是很简单吗,去数据库里查一下有没有不就行了吗,那么假如用户数量…

windows usbip(瑞芯微windows开发)

Rockchip RK3588 windows开发 安装usbipd 除usbipd之外&#xff0c;还有一个usbip仓库可以参考usbip-win&#xff0c;但是相对麻烦一些 windows install winget install usbipdShare Devices usbipd --help usbipd list usbipd bind --busid<BUSID>Remote Connectin…

mysql统计整个数据库记录条数

SELECTSUM(TABLE_ROWS) FROM(SELECTTABLE_NAME,TABLE_ROWSFROMINFORMATION_SCHEMA.TABLESWHERETABLE_SCHEMA 数据名&#xff0c;其他不变) t;效果如下&#xff1a;

算法-贪心算法-简单-买卖股票的最佳时机

记录一下算法题的学习4 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从这…

【设计一个缓存--针对各种类型的缓存】

设计一个缓存--针对各种类型的缓存 1. 设计顶层接口2. 设计抽象类 -- AbstractCacheManager3. 具体子类3.1 -- AlertRuleItemExpCacheManager3.2 -- AlertRuleItemSrcCacheManager 4. 类图关系 1. 设计顶层接口 // 定义为一个泛型接口,提供给抽象类使用 public interface Cach…

Linux命令(123)之mail

linux命令之mail 1.mail介绍 linux命令mail是用来发送邮件 2.mail用法 mail -s "Subject" EmailAddress < EmailMessage 参数说明-s指定邮件主题SubjectEmailAddress指定邮件地址EmailMessage指定邮件内容3.实例 3.1.配置QQ邮件发送 1.安装sendmail/mailx …

ThreadLocal这点牛角尖总算是给我钻明白了

前言 这个问题算是我的一个羞耻点&#xff0c;起源于一次面试中&#xff0c;面试官问ThreadLocal的底层实现是啥&#xff0c;我那时候一直以为ThreadLocal是一个类似于Redis一样的独立于线程外的第三方存储容器&#xff0c;如何底层维护了一个Map结构&#xff0c;以线程ID为Key…

iOS性能优化

了解屏幕成像的原理。 有一个电子枪然后在很多横轴方向上 发射电子&#xff0c;不同横轴的电子枪根据显示器中的硬件时钟产生一系列的定时信号&#xff0c;以此来让电子以不同的时间发射出去 这些电子一瞬间的运动形成了一帧动画。 CPU优化&#xff1a; 1.文本计算优化 如果一…

DSVPN简介

定义 动态智能VPN&#xff08;Dynamic Smart Virtual Private Network&#xff09;&#xff0c;简称DSVPN&#xff0c;是一种在Hub-Spoke组网方式下为公网地址动态变化的分支之间建立VPN隧道的解决方案。 目的 越来越多的企业希望建立Hub-Spoke方式的IPSec VPN网络将企业总部…