【手写 Vuex 源码】第一篇 - Vuex 的基本使用

news2024/11/25 2:41:30

一,前言

本篇开始,进入 vuex 源码学习,本篇主要介绍一下内容:

  • 创建 vuex 源码项目;
  • 介绍 vuex 的基本使用;

二,创建 vuex 源码项目

1,使用 vue-cli 创建 vue2.x 脚手架

vue create source-learning-vuex

脚手架配置项:

Vue CLI v4.5.13
? Please pick a preset: Manually select features
? Check the features needed for your project: 
❯◯ Choose Vue version
 ◉ Babel
 ◯ TypeScript
 ◯ Progressive Web App (PWA) Support
 ◯ Router
 ◯ Vuex
 ◯ CSS Pre-processors
 ◯ Linter / Formatter
 ◯ Unit Testing
 ◯ E2E Testing

2,安装 vuex 依赖

npm install vuex

3,创建 .gitignore 文件

创建 .gitignore 文件,忽略掉不需要版本控制的文件:

// .gitignore

.DS_Store
node_modules
/dist

准备工作完成;


二,vuex 的工作流程

vuex 为项目开发提供了状态管理及数据共享能力;

在项目开发中,使用 vuex 能够将所有的数据统一存储到一个 store 容器中进行管理;

如下图所示,绿色虚线框即为 vuex 的管理范围,表示一个容器:

vuex工作流程.png

  • 在 vuex 中,进行统一的项目状态管理,可以通过 vuex 将状态映射到项目任何组件;
  • 在 vuex 中,通过 mutation 是更新状态的唯一方式;
  • 状态同步更新:通过直接将结果提交到 mutation,实现状态的同步更新;
  • 状态异步更新:通过调用 dispatch 方法,触发对应 action 执行异步操作,并将异步操作的结果提交至 mutation 实现状态的同步更新;
  • 日常项目开发中,也可以借助 vuex 的状态管理特性,实现前端的数据缓存功能;

三,vuex 的基本使用介绍

1,vuex 的核心概念

在 vuex 官方文档中,核心概念共有以下五个:

  • State:状态,可以理解为 vue 组件中的 data 数据;
  • Getter:可以理解为 vue 中的 computed 计算属性;
  • Mutation:同步函数,可以同步更改状态;
  • Action:异步函数,可以执行异步操作,配合 Mutation 实现状态的异步更新;
  • Module: vuex 的模块化,能够将臃肿复杂的 store 容器进行模块化分割,每个模块拥有独立的 state、mutation、action、getter;

2,vuex 插件配置

引入并通过Vue.use(Vuex)安装 vuex 插件,配置并导出 store 实例:

// src/store/index.js

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

// 注册 vuex 插件:内部会调用 Vuex 的 install 方法
Vue.use(Vuex);

// 实例化容器:Vuex.Store
const store = new Vuex.Store({
  // state 状态:相当于组件中的 data 数据
  state: {
    num: 10
  },
  // getters 相当于计算属性(内部实现利用了计算属性)
  getters: {
    
  },
  // 相当于 method,能够同步的更改 state
  mutations: {
    
  },
  // action作用:执行异步操作,并将结果提交给 mutations
  actions: {
    
  }
});

export default store;// 导出 store 实例,传入根组件
备注:此处为简单配置,尚未引入 Vuex 模块化及命名空间概念;

在 main.js 中导入配置完成的 store 实例;

new Vue初始化时,将 store 实例注入根组件:

// main.js

import Vue from 'vue'
import App from './App.vue'
import store from './store/index' // 引入 store 实例

new Vue({
  store,// 将 store 实例注入到 vue 中
  render: h => h(App),
}).$mount('#app');

此时,vuex 插件配置完成,可直接在页面中测试使用;

3,state 的使用

在 App.vue 中, template中直接输出 store 容器中的状态 num:

// src/App.vue

<template>
  <div id="app">
    商品数量: {{this.$store.state.num}} 个<br>
  </div>
</template>

执行 npm run serve 启动服务:

image.png

问题:this.$store.state.num是如何获取到状态的?

这里涉及 Vuex 插件初始化,与 vue-router 安装流程相似;

当执行`Vue.use(Vuex)`时,会调用 install 方法,为每个子组件都混入了当前的 store 容器实例;

new Vue 是根实例;App.vue 是根实例的子组件;

所以,new Vue 中传入的 store 实例,install 时会被混入到 App.vue 组件上;

同理,最终所有组件都将混入来自父组件的 store 实例,从而实现 store 容器实例的共享;

4,getters 的使用

getters 的内部实现依赖了 computed;

所以,可以理解为 Vue 的 computed 计算属性;

// main.js

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

// 注册 vuex 插件:内部会调用 Vuex 中的 install 方法
Vue.use(Vuex);

// 实例化容器容器:Vuex.Store
const store = new Vuex.Store({
  state: {
    num: 10
  },
  getters: {
    // 根据商品数量计算总价格
    getPrice(state) {
      return state.num * 10
    }
  },
});
export default store;

template中,使用用 getters 方法 getPrice:

// src/App.vue

<template>
  <div id="app">
    商品数量: {{this.$store.state.num}} 个<br>
    商品单价: 10 元<br>
    订单金额: {{this.$store.getters.getPrice}} 元<br>
  </div>
</template>

image.png

备注:由于 getters 具备计算属性特性,当依赖的 state 状态改变时,会触发更新;

5,mutation 的使用

在 vuex 中,通过 commit 提交 mutation 是更新状态的唯一方式;

mutation 方法:

  • 第一个参数:state 状态对象;
  • 第二个参数:payload 载荷,本次修改结果;
// src/store/index.js

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

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    num: 10
  },
  mutations: {
    // 更新 num
    changeNum(state, payload) {
      state.num += payload;
    }
  }
});
export default store;

template 中,直接调用 commit 方法提交 mutation,同步更新状态:

// src/App.vue

<template>
  <div id="app">
    商品数量: {{this.$store.state.num}} 个<br>
    商品单价: 10 元<br>
    订单金额: {{this.$store.getters.getPrice}} 元<br>
    <button @click="$store.commit('changeNum',5)">同步更新:数量+5</button>
  </div>
</template>

点击同步更新按钮,触发 mutation 方法,视图更新:

image.png

6,action 的使用

组件通过调用 dispatch 触发 action 执行异步请求返回结果数据,再通过 commit 提交 mutation 完成状态更新;

在 action 方法中:

  • 可以继续调用 dispatch 触发 action;
  • 可以多次调用 commit 进行状态提交;

备注:

  • mutation 方法的目的是修改状态,所以第一个参数是 state 状态;
  • action 方法需要将结果提交到 mutation,所以第一个参数是 store(store 中包含了 commit 方法)
// src/store/index.js

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

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    num: 10
  },
  mutations: {
    changeNum(state, payload) {
      state.num += payload;
    }
  },
  // action作用:执行异步操作,并将结果提交给 mutations
  actions: {
    changeNum({ commit }, payload) {
      setTimeout(() => { // 模拟异步
        commit('changeNum', payload)
      }, 1000);
    }
  }
});

export default store;
备注:这里使用 setTimeout 模拟异步操作;

template 中,直接调用 dispatch 方法触发 action,异步更新状态:

// src/App.vue

<template>
  <div id="app">
    商品数量: {{this.$store.state.num}} 个<br>
    商品单价: 10 元<br>
    订单金额: {{this.$store.getters.getPrice}} 元<br>
    <button @click="$store.commit('changeNum',5)">同步更新:数量+5</button>
    <button @click="$store.dispatch('changeNum',-5)">异步更新:数量-5</button>
  </div>
</template>

点击异步更新按钮,1 秒后,视图更新:

image.png

以上,就是 vuex 几个核心概念的基本用法;


四,结尾

本篇,介绍了 vuex 的基本用法,主要包含以下几个点:

  • vuex 项目创建;
  • vuex 工作流程介绍;
  • vuex 的基本使用介绍;

下一篇,介绍 vuex 的 install 插件安装逻辑;


维护日志

  • 20210918:

    • 优化文章描述,添加了部分代码的意图与注释;

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

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

相关文章

shell脚本(语法)

一、什么是shell脚本 1.1、shell 的两层含义&#xff1a;既是一种应用程序,又是一种程序设计语言 1.1.1、shell是一种应用程序 交互式地解释、执行用户输入的命令&#xff0c;将用户的操作翻译成机器可以识别的语言&#xff0c;完成相应功能称之为 shell 命令解析器。 shell 是…

阳离子交换树脂排钾,选择性吸附钾离子

Tulsimer T-42特级凝胶型强酸性阳离子交换树脂&#xff0c;适用于超纯水系统的混床用阳离子交换树脂 Tulsimer T-42是特级强酸型离子交换树脂&#xff0c;氢 H/钠 Na阳离子交换树脂&#xff0c; 是一款有较的交换容量 ,并同时拥有物理及化学稳定品质。可应用于汽电共生发电厂冷…

excel操作技巧:聊聊关于打印的一些事儿

在之前的学习中&#xff0c;小编给小伙伴们带来了许多关于Excel操作的小技巧&#xff0c;不过最近很多小伙伴在打印上又犯了难题&#xff0c;倒在了最后一步上&#xff0c;实在是亏得很。今天小编就来给大家讲讲打印的那些难事儿&#xff01;难题一&#xff1a; 多列数据打印不…

【Unity】Tomcat 部署项目(3种方式)

一、将Unity WebGL包丢进webapps这是最简单粗暴的方式&#xff1a;将Unity WebGL包丢进tomcat/webapps目录即可。无需修改任何配置文件即可完成部署。使用tomcat10与Unity Pong Game包来做测试。①启动tomcat②将Unity Pong Game包丢进webapps目录浏览器直接访问&#xff1a;lo…

HTTP和HTTPS协议

HTTP协议 HTTP协议是一种应用层的协议&#xff0c;全称为超文本传输协议。 URL URL值统一资源定位标志&#xff0c;也就是俗称的网址。 协议方案名 http://表示的就是协议方案名&#xff0c;常用的协议有HTTP协议、HTTPS协议、FTP协议等。HTTPS协议是以HTTP协议为基础&#…

java面经汇总

Java基础 什么是字节码&#xff1f; jvm可以理解的代码&#xff08;.class文件&#xff09; Java代码从源代码到运行过程&#xff1a; java代码 -> javac编译器->.class字节码文件 -> 解释器&JIT&#xff08;运行时编译器&#xff09;->机器码 JIT编译器会将热…

球面坐标系下的三重积分

涉及知识点 三重积分球面坐标系点火公式一些常见积分处理手法 球面坐标系定义 球面坐标系由方位角φ\varphiφ、仰角θ\thetaθ和距离rrr构成 直角坐标系(x,y,z)(x,y,z)(x,y,z)到球面坐标系的(r,φ,θ)(r,\varphi,\theta)(r,φ,θ)的转化规则如下&#xff1a; {xrsin⁡φco…

使用Python脚本修改Maya ASCII文件路径方法

以下脚本修改当前项目路径和子文件夹中扩展名为“.ma”的所有文件&#xff0c;这样您就可以轻松地一次编辑所有文件。此脚本搜索特定字符串replace_This变量并将其替换为with_This&#xff0c;您可以使用它更改引用路径、纹理路径等… 话不多说直接上脚本&#xff1a; import…

JavaWeb-JavaScropt入门(二)

目录函数语法传参函数表达式作用域对象使用 字面量 创建对象 [常用]使用 new Object 创建对象使用 构造函数 创建对象函数 语法 function 函数名(形参列表) {函数体return 返回值; }那么有了创建函数&#xff0c;肯定有调用函数&#xff1a; // 函数调用 函数名(实参列表) …

聊一聊,我对DDD的关键理解

作者&#xff1a;闵大为 阿里业务平台解决方案团队 当我们在学习DDD的过程中&#xff0c;感觉学而不得的时候&#xff0c;可能会问&#xff1a;我们还要学么&#xff1f;这的确引人深思。本文基于工作经验&#xff0c;尝试谈谈对DDD的一些理解。 一、序 《阿甘正传》中&#xf…

亚马逊要求UL94防火测试阻燃测试标准及项目

UL94认证是什么&#xff1f;分几个等级?是如何表示各等级?带电的产品上架亚马逊都需要相关的UL报告&#xff0c;需要有ISO 17025资质的实验室出具的测试报告才能正常销售和恢复链接&#xff0c;UL94防火测试则是其中一项。UL94试验共有五种&#xff1a;1.B级的水平燃烧试验2.…

Nginx负载均衡

1、概念 访问量太大&#xff0c;一个 Tomcat 扛不住&#xff0c;所以就搭建 Tomcat 集群。让集群中的多个 Tomcat 服务器实例分担负载。 纵向扩容和横向扩容&#xff1a; 纵向扩容&#xff1a;给单台服务器提升硬件的配置。例如&#xff1a;提升 CPU、增加内存、扩大带宽、扩…

关于华为网络设备操作系统的介绍

1、什么是VRP VRP是华为公司数据通信产品的通用操作系统平台&#xff0c;作为华为公司从低端到核心的全系列路由器、以太网交换机、业务网关等产品的软件核心引擎。 功能&#xff1a;实现统一的用户界面和管理界面、实现控制平面功能&#xff0c;并定义转发平面接口规范、实现…

量子比特大突破!原子薄材料成为“救世主”

&#xff08;图片来源&#xff1a;网络&#xff09;量子计算是一项极其复杂的技术&#xff0c;现阶段的一些挑战正严重阻碍着它的发展&#xff0c;尤其是量子比特的小型化和质量问题。IBM计划在2023年实现具有1121个超导量子比特的处理器。以目前的技术手段&#xff0c;要达到这…

大数据框架之Hadoop:入门(二)从Hadoop框架讨论大数据生态

第2章 从Hadoop框架讨论大数据生态 2.1 Hadoop是什么 Hadoop是一个由Apache基金会所开发的分布式系统基础架构。主要解决&#xff0c;海量数据的存储和海量数据的分析计算问题。广义上来说&#xff0c;Hadoop通常是指一个更广泛的概念-Hadoop生态圈。 2.2 Hadoop发展历史 1&…

引入汇丰完成C+轮融资,镁信健康有何资本“魅力”?

近日&#xff0c;上海镁信健康科技股份有限公司&#xff08;下称“镁信健康”&#xff09;宣布完成C轮融资&#xff0c;引入汇丰集团作为战略投资者。镁信健康近两年是资本市场货真价实的“香饽饽”&#xff0c;2021年&#xff0c;完成B轮和C轮两轮融资&#xff0c;融资金额合计…

基于merlin使用chatGPT进行对话

最近chatGPT很热&#xff0c;大家都想试用它。但由于各种限制&#xff0c;一般情况下国内不能试用。 下面给大家介绍基于merlin使用chatGPT&#xff08;目前每天只有11次问答次数&#xff09;。 1 打开merlin页面 访问地址merlin.foyer.work&#xff0c;点击“add to chro…

深入Kafka核心设计与实践原理读书笔记第二章

1 生产者 生产逻辑 配置生产者客户端参数及创建相应的生产者实例。构建待发送的消息。发送消息关闭实列 参数说明 bootstrap.servers &#xff1a;用来指定生产者客户端链接Kafka集群搜需要的broker地址清单&#xff0c;具体格式 host1:port1,host2:port2,可以设置一个或多…

Sentinel-线程隔离和熔断降级

一、线程隔离 ​​​​ 总结 线程隔离的两种手段是&#xff1f; 信号量隔离线程池隔离信号量隔离的特点是&#xff1f; 基于计数器模式&#xff0c;简单&#xff0c;开销小线程池隔离的特点是&#xff1f; 基于线程池模式&#xff0c;有额外开销&#xff0c;但隔离控制更强 二…

为什么在容器中 1 号进程挂不上 arthas?

作者&#xff1a;卜比 本文是《容器中的 Java》系列文章之 4/n &#xff0c;欢迎关注后续连载 &#x1f603; 。 系列1&#xff1a;JVM 如何获取当前容器的资源限制&#xff1f; 系列2&#xff1a;Java Agent 踩坑之 appendToSystemClassLoaderSearch 问题 系列3&#xff1a;让…