手写vuex4源码(八)插件机制实现

news2025/6/21 1:12:07

一、插件的使用

Vuex 不仅提供了全局状态管理能力,还进一步提供了插件机制,便于开发者对 Vuex 插件进行增强;

Vuex 插件的使用方式:通过 Store 类提供的 plugin 数组进行 Vuex 插件注册:

export default createStore({
  plugins:[ //插件会按照注册的顺序依次执行插件,执行的时候会把store传递给你
    customlugin
  ],
...})

二、vuex持久化插件开发

1、customlugin插件介绍

在使用 Vuex 插件进行状态管理时,一定会遇到一个问题:当页面刷新时(如使用 F5 进行刷新),将导致页面状态丢失
为了防止vuex的数据,开发customlugin插件

2、customlugin插件实现

(1)vuex插件实现

  • 创建一个 Vuex 插件,最终导出一个高阶函数(在 plugin 数组中进行插件注册);
  • store.subscribe:订阅方法,当 mutation 方法触发时会触发这个方法
  • store.replaceState:替换方法,可以不通过mutation更新state的值

(2)customlugin实现原理

  • 创建一个函数:customPlugin,vuex初始化时,对插件进行注册和初始化操作
  • 使用 store.subscribe 订阅方法:当 mutation 方法触发时,将当前状态保存到本地
  • 当页面刷新时,状态将会丢失,同时 Vuex 插件重新初始化,此时重新读取本地状态,并通过store.replaceState将本地状态(即刷新丢失的状态)替换到 Vuex 状态,实现状态的持久化效果;
import { createStore } from '@/vuex' // new Store

function customPlugin(store) {
    let local = localStorage.getItem('VUEX:STATE');
    //如果localstorage中存在VUEX:STATE,则取出给vuex赋值
    if (local) {
        store.replaceState(JSON.parse(local))
    }
    store.subscribe((mutation, state) => { // 每当状态发生变化 (调用了mutation的时候 就会执行此回调)
        localStorage.setItem('VUEX:STATE', JSON.stringify(state))
    })
}


const store = createStore({
    plugins: [ // 会按照注册的顺序依次执行插件,执行的时候会把store传递给你
        customPlugin
    ],
    ...
})

在这里插入图片描述

三、实现插件机制

1、注册plugin

  • 在store中的数据和方法定义完成后,挨个初始化plugin中的方法
  • 收集 Vuex 插件中,通过 store.subscribe 订阅状态变化事件的回调函数 fn 保存到 _subscribes 数组中;
export default class Store {
...
    constructor(options) {
    
        // 定义状态
        const state = store._modules.root.state; // 根状态
        installModule(store, state, [], store._modules.root);
        resetStoreState(store, state);

        store._subscribes = [];
        options.plugins.forEach(plugin => plugin(store));
    }
    // 将回调统计到_subscribes数组中
    subscribe(fn) {
        this._subscribes.push(fn);
    }
}

2、subscribe 状态订阅实现

当mutations方法执行时,依次执行_subscribes中的方法,将当前的mutation方法和state一起传递过去,执行当时定义的将数据存在localStorage的方法

commit = (type, payload) => {
    const entry = this._mutations[type] || [];
    this._withCommit(() => {
      entry.forEach((handler) => handler(payload));
    });
    this._subscribes.forEach((sub) => sub({ type, payload }, this.state));
  };

3、replaceState 状态替换实现

replaceState 传入的是本地存储中的state,由于在严格模式下不通过mutation给state赋值会报错,所以在这里借助_withCommit方法,mutation中为了防止异步和其余方法该值也是通过这个进行判断的

 replaceState(newState) {
    // 严格模式下不能直接更改状态
    this._withCommit(() => {
      this._state.data = newState;
    });
  }

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

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

相关文章

ModuleNotFoundError:No module named “te_fusion“

Asecend Tensor Compiler简称ATC,昇腾张量编译器,主要是将开源框架的网络模型或Ascend IR定义的单算子描述文件(json格式)转换为昇腾AI处理器支持的om格式 场景描述:ONNXRuntime调用CANN后端执行时,报了没有找到te_fusion的error&#xff0c…

多项式特征应用案例

多项式特征应用案例 描述 对于线性模型而言,扩充数据的特征(即对原特征进行计算,增加新的特征列)通常是提升模型表现的可选方法,Scikit-learn提供了PolynomialFeatures类来增加多项式特征(polynomial fea…

JavaScript【一】JavaScript变量与数据类型

文章目录🌟前言🌟变量🌟 变量是什么?🌟 变量提升🌟 声明变量🌟 JavaScript有三种声明方式🌟 命名规范🌟 注意🌟数据类型以及运算🌟 检测变量数据类…

【Linux】System V IPC-命名管道共享内存消息队列

System V IPC-命名管道&共享内存&消息队列命名管道共享内存创建共享内存附加和分离共享内存消息队列消息队列的接口命名管道 使用mkfifo命令,创建一个命名管道,通过ll可以查看当前命名管道的类型 p类型,也就是pipe管道类型。 之前我…

Docker镜像之Docker Compose讲解

文章目录1 docker-compose1.1 compose编排工具简介1.2 安装docker-compose1.3 编排启动镜像1.4 haproxy代理后端docker容器1.5 安装socat 直接操作socket控制haproxy1.6 compose中yml 配置指令参考1.6.1 简单命令1.6.2 build1.6.3 depends_on1.6.4 deploy1.6.5 logging1.6.6 ne…

【C++进阶】01:概述

概述 OVERVIEW概述C11新特性:C14新特性:C17新特性:C20新特性:C程序编译过程C内存模型CSTL1.Queue&Stack2.String3.MapC语言C语言面向过程编程✅✅面向对象编程(类和对象)❌✅泛型编程、元编程&#xff…

基于PaddlePaddle的图片分类实战 | 深度学习基础任务教程系列

图像相比文字能够提供更加生动、容易理解及更具艺术感的信息,图像分类是根据图像的语义信息将不同类别图像区分开来,是图像检测、图像分割、物体跟踪、行为分析等其他高层视觉任务的基础。图像分类在安防、交通、互联网、医学等领域有着广泛的应用。 一般…

LeetCode:77. 组合——回溯法,是暴力法?

🍎道阻且长,行则将至。🍓 🌻算法,不如说它是一种思考方式🍀算法专栏: 👉🏻123 一、🌱77. 组合 题目描述:给定两个整数 n 和 k,返回范…

风场数据抓取程序实现(java+python实现)

一、数据源参数定义 关键参数代码: package com.grab.catchWindData.pram;/*** ClassName: DevPrams* Description: TODO**/ public class DevPrams {public static String lev_0to0p1_m_below_ground "lev_0-0.1_m_below_ground";public static Stri…

【微服务笔记08】微服务组件之Hystrix实现请求合并功能

这篇文章,主要介绍微服务组件之Hystrix实现请求合并功能。 目录 一、Hystrix请求合并 1.1、什么是请求合并 1.2、请求合并的实现 (1)引入依赖 (2)编写服务提供者 (3)消费者(Se…

React | 认识React开发

✨ 个人主页:CoderHing 🖥️ Node.js专栏:Node.js 初级知识 🙋‍♂️ 个人简介:一个不甘平庸的平凡人🍬 💫 系列专栏:吊打面试官系列 16天学会Vue 11天学会React Node专栏 &#x…

【分享】免梯子的GPT,玩 ChatGPT 的正确姿势

火了一周的 ChatGPT,HG 不允许还有小伙伴不知道这个东西是什么?简单来说就是,你可以让它扮演任何事物,据说已经有人用它开始了颜色文学创作。因为它太火了,所以,本周特推在几十个带有“chatgpt”的项目中选…

双交叉注意学习用于细粒度视觉分类和目标重新识别

目录Dual Cross-Attention Learning for Fine-Grained Visual Categorization and Object Re-Identification摘要本文方法消融实验Dual Cross-Attention Learning for Fine-Grained Visual Categorization and Object Re-Identification 摘要 目的: 探索了如何扩展…

JDK8——新增时间类、有关时间数据的交互问题

目录 一、实体类 二、数据库 三、数据交换 四、关于LocalDateTime类型 (java 8) 4.1 旧版本日期时间问题 4.2 新版日期时间API介绍 4.2.1 LocalDate、LocalTime、LocalDateTime 4.2.2 日期时间的修改与比较 4.2.3 格式化和解析操作 4.2.4 Instant: 时间戳 4.2.5 Duration 与…

Doris(6):数据导入(Load)之Stream Load

Broker load是一个同步的导入方式,用户通过发送HTTP协议将本地文件或者数据流导入到Doris中,Stream Load同步执行导入并返回结果,用户可以通过返回判断导入是否成功。 1 适用场景 Stream load 主要适用于导入本地文件,或通过程序…

小厂实习要不要去?

大家好,我是帅地。 最近暑假实习招聘,不少 训练营 学员都拿到了小厂实习来保底,但是很多小厂基本要求一周内给答复,中大厂就还在流程之中,所以很纠结小厂实习要不要去。 不知道你是否有这样的纠结,今天帅地…

【测试面试汇总2】

目录Linux操作系统1.Linux操作命令2.在Linux中find和grep的区别?3.绝对路径用什么符号表示?4.当前目录、上层目录用什么表示?5.主目录用什么表示?6.怎么查看进程信息?7.保存文件并退出vi 编辑?8.怎么查看当前用户id&a…

【Python从入门到进阶】15、函数的定义和使用

接上篇《14、字典高级应用》 上一篇我们学习了有关字典的高级应用操作(字典的增删改查),本篇我们来学习Python中函数的定义和使用,包括函数的参数、返回值、局部变量和全景变量等操作。 一、一个思考 例如这里有一段大东北洗浴中…

2023年PMP报考时间安排攻略!

1.2023年PMP考试时间 PMP一年开考4次,分别为3月、6月、9月、12月,预计2023年PMP第一次考试时间在2023年3月左右,具体以基金会官方通知为准。 1)为什么考PMP? 大部分人考 PMP 无非以下几个原因,总的来说&…

运行时内存数据区之程序计数器

内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的实时选行。JVM内存布局规定了Java在运行过程中内存申请、分配、管理的策略,保证了JVM的高效稳定运行。 不同的VM对于内存的划分方式和管理机制存在着部分差…