Vue--》详解状态管理工具——Vuex

news2024/11/28 1:46:48

目录

vuex

搭建vuex环境

vuex的使用

vuex开发者工具使用

getters

mapState和mapGetters

mapMutations和mapActions

多组件共享数据 

vuex实现模块化


vuex

专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。vuex的应用场景是:多个组件依赖于同一状态、来自不同组件行为需要变更同一状态。说白了就是想共享!

其官方文档为:vuex ,其工作原理图如下图所示:Vuex中的三个函数都是在同一个仓库store里面的,actions一般用于发送Ajax请求,当然日常开发中,如果没有特别的要求,actions也可以省略而让数据去直接访问mutations也是可以的。

搭建vuex环境

在2022年2月7日,vue3成为默认版本,vue3成为默认版本的同时vuex也更新到4版本,而vuex的最新版本只支持vue3项目,如果想在vue2中使用vuex,需下载vuex3版本。

在Vue2项目中使用vuex,安装命令如下:

npm install vuex@3

创建文件:src/store/index.js

// 该文件用于创建 Vuex 中的核心store
// 引入 Vue
import Vue from 'vue'
// 引入 Vuex
import Vuex from 'vuex'
// 使用插件
Vue.use(Vuex)

// 准备actions——用于响应组件中的动作
const actions = {}
// 准备mutations——用于操作数据(state)
const mutations = {}
// 准备state——用于存储数据
const state = {}

// 创建并导出store 
export default new Vuex.Store({
  actions,
  mutations,
  state,
})

在main.js中传入 store 配置项

vuex的使用

我们可以将求和的sum放置在vuex中的state中,将该值设置为共享,即写在vm上。代码如下:

<template>
  <div>
    <h1>当前求和为:{{ $store.state.sum }}</h1>
    <select v-model.number="n">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
    </select>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
    <button @click="incrementOdd">当前求和为奇数再加</button>
    <button @click="incrementWait">等一等再加</button>
  </div>
</template>

<script>
export default {
  name:'Count',
  data(){
    return {

      n:1 // 用户选择数字
    }
  },
  methods:{
    increment(){
      this.$store.dispatch('jia',this.n)
    },
    decrement(){
      this.$store.dispatch('jian',this.n)
    },
    incrementOdd(){
      if(this.$store.state.sum % 2){
        this.$store.dispatch('jia',this.n)
      }
    },
    incrementWait(){
      setTimeout(()=>{
        this.$store.dispatch('jia',this.n)
      },1000)
    }
  }
}
</script>

<style lang="less" scoped>
  button{
    margin-left: 5px;
  }
</style>
// 该文件用于创建 Vuex 中的核心store
// 引入 Vue
import Vue from 'vue'
// 引入 Vuex
import Vuex from 'vuex'
// 使用插件
Vue.use(Vuex)

// 准备actions——用于响应组件中的动作
const actions = {
  jia(context,value){
    // console.log('actions中的jia被调用了');
    context.commit('JIA',value)
  },
  jian(context,value){
    // console.log('actions中的jia被调用了');
    context.commit('JIAN',value)
  }
}
// 准备mutations——用于操作数据(state)
const mutations = {
  JIA(state,value){
    state.sum+=value
  },
  JIAN(state,value){
    state.sum-=value
  }
}
// 准备state——用于存储数据
const state = {
  sum:0, // 当前的和
}

// 创建并导出store 
export default new Vuex.Store({
  actions,
  mutations,
  state,
})

当然我们也可以将条件逻辑直接写到actions里面即可,如下:

actions中的一些基础函数,也可以省略而让数据直接去操控mutations,如下:

vuex开发者工具使用

vuex和vue开发者工具都是整合到一起的,所以不需要在下载工具,直接使用vue开发者工具即可

我们点击按钮,Vuex会监听到你当前执行的函数以及数据发生的时间及其变化。

getters

有时候我们需要从 store 中的 state 中派生出一些状态,如果有多个组件需要用到此属性,我们要么复制这个函数,或者抽取到一个共享函数然后在多处导入它——无论哪种方式都不是很理想。Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。

mapState和mapGetters

mapState方法:用于帮助我们映射 state 中的数据为计算属性:

computed:{
  // 程序员自己手写
  name(){
    return this.$store.state.name
  },
  age(){
    return this.$store.state.age
  },
  // 程序员借助vuex提供的方法 mapState 生成计算属性(对象写法)
  ...mapState({name:'name',age:'age'}),
  // 程序员借助vuex提供的方法 mapState 生成计算属性(数组写法)
  ...mapState(['name','age'])
},

mapGetters方法:用于帮助我们映射getters中的数据为计算属性:

computed:{
  // 程序员自己手写
  bigSum(){
    return this.$store.getters.sum
  },
  // 程序员借助vuex提供的方法 mapState 生成计算属性(对象写法)
  ...mapGetters({bigSum:'bigSum'}),
  // 程序员借助vuex提供的方法 mapState 生成计算属性(数组写法)
  ...mapGetters(['bigSum']),
},

mapMutations和mapActions

mapMutations与mapActions使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。

mapMutations:用于帮助我们生成与 mutations 对话的方法,即:包含$store.commit(xxx)的函数

methods:{
  // 程序员自己手写
  increment(){
    this.$store.commit('JIA',this.n)
  },
  decrement(){
    this.$store.commit('JIAN',this.n)
  },
  // 使用 mapMutations 方法,简化方法书写(对象方式)
  ...mapMutations({increment:'JIA',decrement:'JIAN'}),
  // 使用 mapMutations 方法,简化方法书写(数组方式)
  ...mapMutations(['JIA','JIAN']),
}

使用对象方式,点击事件调用函数时,需要将指定的用户选择增加的数字作为形参传入:

使用数组方式,点击事件调用函数时,名称需要和数组中的元素保持一致:

mapActions:用于帮助我们生成与actions对话的方法,即:包含$store.dispatch(xxx)的函数

methods:{
  // 程序员自己手写
  incrementOdd(){
    this.$store.dispatch('jiaOdd',this.n)
  },
  incrementWait(){
    this.$store.dispatch('jiaWait',this.n)
  },
  // 使用 mapActions 方法,简化方法书写(对象方式)
  ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
  // 使用 mapActions 方法,简化方法书写(数组方式)
  ...mapActions(['jiaOdd','jiaWait'])
}

和mapMutations方法类似,使用对象形式,也需要传入需要将指定的用户选择增加的数字作为形参传入:

和mapMutations方法类似,使用数组方式,点击事件调用函数时,名称需要和数组中的元素保持一致:

多组件共享数据 

当我们想进行多组件共享时,将要共享的数据写到 state 里面:

创建person组件,来获取公共是数据person

<template>
  <div>
    <h1>人员列表</h1>
    <h2>Count组件的求和为:{{sum}}</h2>
    <input type="text" placeholder="请输入名字" v-model="name">
    <button @click="add">添加</button>
    <ul>
      <li v-for="p in personList" :key="p.id">{{p.name}}</li>
    </ul>
  </div>
</template>
<script>
import {nanoid} from 'nanoid'
export default {
  data(){
    return {
      name:""
    }
  },
  computed:{
    personList(){
      return this.$store.state.personList
    },
    sum(){
      return this.$store.state.sum
    }
  },
  methods:{
    add(){
      const personObj = {id:nanoid(),name:this.name}
      this.$store.commit('ADD_PERSON',personObj)
      this.name=''
    }
  }
}
</script>

因为personList是写到公共数据上,即为共享数据,想用的组件之间用mapState调用即可:

调用完,直接引用即可:

其具体实现过程,如下:

vuex实现模块化

在大型项目中,如果想使用vuex肯定不可能将所有的配置都写在一起,因为这样难免会发生冲突,所以就需要对vuex进行模块化,如下:

两者的vuex结果给出如下,给与书写规范参考:

// 共享数值数据
const countOptions = {
  // 开启命名空间
  namespaced: true,
  // 准备actions——用于响应组件中的动作
  actions:{  
    jiaOdd(context,value){
      if(context.state.sum % 2){
        context.commit('JIA',value)
      }
    },
    jiaWait(context,value){
      setTimeout(()=>{
        context.commit('JIA',value)
      },500)
    }},
  // 准备mutations——用于操作数据(state)
  mutations:{
    JIA(state,value){
      state.sum+=value
    },
    JIAN(state,value){
      state.sum-=value
    },
  },
  // 准备state——用于存储数据
  state:{
    sum:0, // 当前的和
    name:'张三',
    age:18,
  },
  // 准备getters用于将state中的数据进行加工
  getters:{
    bigSum(state){
      return state.sum*20
    }
  }
}

// 共享人员数据
const personOptions = {
  namespaced:true,
  actions:{
    addPersonName(context,value){
      if(value.name.indexOf('王')===0){
        context.commit('ADD_PERSON',value)
      }else{
        alert('添加的人必须姓王')
      }
    },
    addPersonAxiosName(context){
      axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then(
        response=>{
          context.commit('ADD_PERSON',{id:nanoid(),name:response.data})
        },
        err=>{
          alert(err.message)
        }
      )
    }
  },
  mutations:{
    ADD_PERSON(state,value){
      state.personList.unshift(value)
    }
  },
  state:{
    personList:[
      {id:'001',name:'张三'}
    ]
  },
  getters:{
    firstPersonName(state){
      return state.personList[0].name
    }
  }
}

我们将vuex进行模块化分组,那么调用这个共享的数据的方法肯定不能和之前的一样了,要进行一定的变化,不知道有没有发现,我们在进行模块化分组的时候是需要使用命名空间 namespace 的配置项,这种重点!!!,调用共享数据方式如下:

如果不想使用vuex内置的函数方法,单纯的从vm上一层层的调用模块化后的数据的话,它的书写方式也和一般方式不同,如下:

当然我们调用methods方法时也是一致的:

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

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

相关文章

c语言进阶(4)——字符函数的详细解析

文章目录1.strlen函数2.strcpy函数3.strcat函数4.strcmp函数5.strncpy函数6.strncat函数7.strncmp函数8.strstr函数9.strtok函数10. strerror函数11. 相关字符转换函数12.字符转换函数1.strlen函数 size_t strlen( const char *string ); 用途&#xff1a;用来计算字符串长度的…

【云原生进阶之容器】第二章Controller Manager原理2.8节--Resync机制

8 Resync机制 8.1 DeltaFIFO队列为什么需要Resync 为什么需要 Resync 机制呢?因为在处理 SharedInformer 事件回调时,可能存在处理失败的情况,定时的 Resync 让这些处理失败的事件有了重新 onUpdate 处理的机会。 主要的目的是为了不丢数据,处理 resync 机制还有边缘触发与…

公务员考试催生一家上市公司,公务员真的是一条好的出路吗

公务员考试能催生一家公司吗&#xff1f;还真的可以&#xff0c;而且在2023.01.09日也就是今天上市。公务员真的是一条好的出路吗&#xff0c;现在考公务员还行不行&#xff1f;这需要结合我们当下的环境来综合分析。我们都经历了疫情&#xff0c;期间各个大厂频频将裁员大棒挥…

《Spring揭秘》读书笔记 1:IoC和AOP

1 Spring框架的由来 Spring框架的本质&#xff1a;提供各种服务&#xff0c;以帮助我们简化基于POJO的Java应用程序开发。 各种服务实现被划分到了多个相互独立却又相互依赖的模块当中&#xff1a; Core核心模块&#xff1a;IoC容器、Framework工具类。 AOP模块&#xff1a;S…

如何抓住风口,利用互联网赚钱?(內含三大商业模式推荐)建议收藏

大家好&#xff0c;我是你们熟悉而又陌生的好朋友梦龙&#xff0c;一个创业期的年轻人 今天跟你做个分享&#xff0c;众所周知互联网是一块非常大的蛋糕&#xff0c;几位互联网巨头也做不到完全吃透&#xff0c;同时也是一个门槛较低的创业之路&#xff0c;非常的适合年轻人&a…

8、Javaweb_ServlethttpRequst

Servlet&#xff1a; 1. 概念 2. 步骤 3. 执行原理 4. 生命周期 5. Servlet3.0 注解配置 6. Servlet的体系结构 Servlet -- 接口 | GenericServlet -- 抽象类 | HttpServlet -- 抽象类 * GenericServlet&#xff1a;将Servlet接口中其他的方…

C语言-指针进阶-常见笔试面试题详解(9.4)

目录 思维导图&#xff1a; 指针和数组笔试题 指针笔试题 写在最后&#xff1a; 思维导图&#xff1a; 指针和数组笔试题 只有多刷题&#xff0c;才能巩固提高所学的知识。 例1&#xff1a; #include <stdio.h>int main() {//一维数组int a[] { 1,2,3,4 };//求出…

「精研科技」× 企企通,全球MIM龙头借助采购供应商数字化向多领域突破

近日&#xff0c;金属粉末注射成型&#xff08;MIM&#xff09;龙头企业江苏精研科技股份有限公司&#xff08;以下简称“精研科技”&#xff09;与企企通达成合作。双方将共同构建完整的采购管理和供应商协同平台&#xff0c;加强供应商管理&#xff0c;提高采购效率&#xff…

Netty源码性能分析 - ThreadLocal PK FastThreadLocal

序 既然jdk已经有ThreadLocal&#xff0c;为何netty还要自己造个FastThreadLocal&#xff1f;FastThreadLocal快在哪里&#xff1f;这需要从jdk ThreadLocal的本身说起。在java线程中&#xff0c;每个线程都有一个ThreadLocalMap实例变量&#xff08;如果不使用ThreadLocal&…

使用Alexnet实现CIFAR100数据集的训练

如果对你有用的话&#xff0c;希望能够点赞支持一下&#xff0c;这样我就能有更多的动力更新更多的学习笔记了。&#x1f604;&#x1f604; 使用Alexnet进行CIFAR-10数据集进行测试&#xff0c;这里使用的是将CIFAR-10数据集的分辨率扩大到224X224&#xff0c;因为在测试…

【ROS】—— ROS常用组件_TF坐标变换_多态坐标变换与TF坐标变换实操(十一)

文章目录前言1. 多态坐标变换1.1 发布方1.2 订阅方(C)1.3 订阅方(python)2. 坐标系关系查看3. TF坐标变换实操(C)3.1准备3.2 生成新的乌龟3.3 增加键盘控制3.4 发布方(发布两只乌龟的坐标信息)3.5 订阅方(解析坐标信息并生成速度信息)前言 &#x1f4e2;本系列将依托赵虚左老师…

将git仓库瘦身

一个小工具的仓库居然有7个g了&#xff0c;每次clone都要等好久&#xff0c;在网上找的方法&#xff0c;实际了几个小时才成功瘦身&#xff0c;做一次记录 一、排查是哪些历史文件占用了内存&#xff0c;下面是查询最大的5个文件 git rev-list --objects --all | grep "$(…

使用nvm管理node版本,实现高版本与低版本node之间的转换

第一步&#xff1a;先清空本地安装的node.js版本 1.按健winR弹出窗口&#xff0c;键盘输入cmd,然后敲回车&#xff08;或者鼠标直接点击电脑桌面最左下角的win窗口图标弹出&#xff0c;输入cmd再点击回车键&#xff09; 然后进入命令控制行窗口&#xff0c;并输入where node查…

Linux环境配置

一、安装ubuntu16的步骤 1、新建Ubuntu 右击文件---------新建虚拟机 典型----------------下一步 稍后安装操作系统-------------下一步 Linux&#xff08;L&#xff09;------------------Ubuntu64位-----------------下一步 虚拟机名称&#xff08;随意起&#xff09;----…

OSS简单介绍

OSS 阿里云对象存储OSS&#xff08;Object Storage Service&#xff09;是一款海量、安全、低成本、高可靠的云存储服务&#xff0c;可提供99.9999999999%&#xff08;12个9&#xff09;的数据持久性&#xff0c;99.995%的数据可用性。多种存储类型供选择&#xff0c;全面优化…

197: vue+openlayers 预加载preload瓦片地图,减少过渡期间的空白区域

第197个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+openlayers项目中演示瓦片预加载和没有预加载的不同状态。 没有采用预加载 当我们平移和缩放地图时,经常会遇到过渡期间的空白区域(因为内容正在加载),过一会儿,切片图像才出现了。 采用预加载,将预载的值设置为…

深入ReentrantLock锁

1. 前言 今天我们来探讨下另一个核心锁ReentrantLock. 从具体的实现到JVM层面是如何实现的。 我们都会一一进行讨论的&#xff0c;好了&#xff0c;废话不多说了&#xff0c;我们就开始吧 2. ReentrantLock 以及synchronized 核心区别&#xff1a; ReentrantLock 是一个抽象的…

MVC框架知识详解

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;Java案例分…

机器学习课程学习随笔

文章目录本文来源机器学习简介机器学习流程机器学习可以完成如下功能&#xff1a;机器学习应用场景金融领域零售领域机器学习分类机器学习实现基于python等代码自己实现本文来源 本博客 是通过学习亚马逊的官方机器学习课程的随笔。 课程参考链接https://edu.csdn.net/course/…

爬虫与反爬虫 - 道高一尺魔高一丈 - 2013最新 - JS逆向 - Python Scrapy实现 - 爬取某天气网站历史数据

目录 背景介绍 网站分析 第1步&#xff1a;找到网页源代码 第2步&#xff1a;分析网页源代码 Python 实现 成果展示 后续 Todo 背景介绍 今天这篇文章&#xff0c;3个目的&#xff0c;1个是自己记录&#xff0c;1个是给大家分享&#xff0c;还有1个是向这个被爬网站的前…