手写一个vuex?

前言

vuex是一种专为Vue.js应用程序开发的状态管理模式,挂载在全局中,具有响应式特性

vuex的实现原理主要包括以下几个方面:

  • 是一个对象,vuex有两个属性,一个是Store类,一个是install方法。
  • Store类:用来创建store实例的,它接收一个对象作为参数,包含state, getters, mutations, actions等属性。
  • install方法:用来将store实例注入到每个Vue组件中的,它利用了Vue的mixin机制,在beforeCreate钩子中执行vuexInit方法,将store实例挂载到每个组件的$store属性上。
  • state:利用Vue的响应式data实现的,它将用户传入的state对象作为new Vue的data选项,从而实现了state的数据响应。
  • getters:利用Vue的计算属性computed实现的,它将用户传入的getters对象作为new Vue的computed选项,从而实现了getters的缓存和依赖追踪。
  • vuex的mutations是用来同步修改state的方法,它只能接收两个参数,一个是state,一个是payload,它必须是同步函数,不能包含异步操作。
  • actions:用来异步修改state的方法,它可以接收一个context对象作为参数,包含state, getters, commit, dispatch等属性,它可以包含异步操作,但最终还是要通过commit调用mutations来修改state。
  • vuex还提供了一些辅助函数,如mapState, mapGetters, mapMutations, mapActions等,用于简化组件中的store访问和操作。

下面是一个简单的代码示例,用于说明vuex的实现原理:

// vuex.js
let Vue // 保存Vue构造函数,插件中要使用class Store {constructor(options) {// 保存选项this.$options = options// 定义响应式的statethis._vm = new Vue({data: {$$state: options.state // 加两个$,Vue不做代理},computed: options.getters // 将getters定义为计算属性})// 定义commit和dispatch方法this.commit = this.commit.bind(this)this.dispatch = this.dispatch.bind(this)// 定义wrappedGettersthis.wrappedGetters = {}// 实现getters,按照getters的定义挂载到store实例const computed = {}Object.keys(this.$options.getters).forEach(key => {// 获取用户定义的getterconst fn = this.$options.getters[key]// 转换为computed可以使用无参数形式computed[key] = () => {return fn(this.state, this.getters)}// 为wrappedGetters定义只读属性Object.defineProperty(this.wrappedGetters, key, {get: () => this._vm[key]})})// 实现mutationsthis.mutations = {}Object.keys(this.$options.mutations).forEach(key => {this.mutations[key] = payload => {this.$options.mutationskey}})// 实现actionsthis.actions = {}Object.keys(this.$options.actions).forEach(key => {this.actions[key] = payload => {this.$options.actionskey}})}// 存取器,state只读get state() {return this._vm._data.$$state}set state(v) {console.error('不能直接修改state,请使用replaceState')}// 存取器,getters只读get getters() {return this.wrappedGetters}// commit,执行mutationcommit(type, payload) {// 获取type对应的mutationconst fn = this.mutations[type]if (!fn) {// 未定义的mutationconsole.error(`mutation ${type} 不存在`)return}// 传入state和负载fn(payload)}// dispatch,执行actiondispatch(type, payload) {// 获取type对应的actionconst fn = this.actions[type]if (!fn) {// 未定义的actionconsole.error(`action ${type} 不存在`)return}// 传入当前Store实例和负载return fn(payload)}
}// install方法
function install(_Vue) {Vue = _Vue // 保存Vue构造函数// 混入Vue.mixin({beforeCreate() {// 此时,上下文已经是组件实例了// 如果this是根实例,则它的$options里面会有store实例if (this.$options.store) {Vue.prototype.$store = this.$options.store// 以后就能在组件中拿到 $store}}})
}// 导出对象
export default { Store, install }

然后在app.js文件中引入使用

// 引入Vue和Vuex
import Vue from 'vue'
import Vuex from 'vuex'// 使用Vuex插件
Vue.use(Vuex)// 创建一个store实例
const store = new Vuex.Store({// 定义statestate: {count: 0},// 定义gettersgetters: {doubleCount: state => state.count * 2},// 定义mutationsmutations: {increment(state, payload) {state.count += payload}},// 定义actionsactions: {incrementAsync(context, payload) {setTimeout(() => {context.commit('increment', payload)}, 1000)}}
})// 在组件中使用store
new Vue({el: '#app',store,...
})

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

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

相关文章

procise纯PL流程点灯记录

procise纯PL流程点灯记录 一、概述 此篇记录使用procise工具构造JFMQL15T 纯PL工程,显示PL_LED闪烁; 硬件说明如下: 时钟引脚 Pl_CLK: U2 ,IO_L14P_T2_SRCC_34 PL_LED1 : E2, IO_L17P_T2_AD5P_35 PL_LED2: D6, IO_L2N_T0_AD8N_35 PL_LED3 :…

.NET CORE 无法调试 当前不会命中断点

多个项目直接可以设置项目的属性->生成->输出的配置文件输出地址 然后路径统一输入该项目的bib/debug/.netcorex.x就可以了

【JAVA】黑马MybatisPlus 学习笔记【终】【插件功能】

4.插件功能 MybatisPlus提供了很多的插件功能,进一步拓展其功能。目前已有的插件有: PaginationInnerInterceptor:自动分页TenantLineInnerInterceptor:多租户DynamicTableNameInnerInterceptor:动态表名OptimisticL…

197. 上升的温度

197. 上升的温度 表: Weather ---------------------- | Column Name | Type | ---------------------- | id | int | | recordDate | date | | temperature | int | ---------------------- id 是该表具有唯一值的列。 该表包含特定日期的温度信息 编写解决方案…

【Linux】生产者消费者模型(阻塞队列与环形队列)和POSIX信号量

文章目录 一、生产者消费者模型二、基于BlockingQueue的生产者消费者模型1.BlockQueue.hpp2.Task.hpp3.main.cc 三、POSIX信号量四、基于环形队列的生产消费模型1.RingQueue.hpp2.Task.hpp3.main.cc 一、生产者消费者模型 我们这里举一个例子,来解释生产者消费者模…

【数据结构和算法】寻找数组的中心下标

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 前缀和的解题模板 2.1.1 最长递增子序列长度 2.1.2 寻找数组中第 k 大的元素 2.1.3 最长公共子序列…

雷盛红酒和云仓酒庄的优势

多国家采购、多葡萄酒品种、多价位区间的全系列整体品牌形式的雷盛(LEESON)红酒云仓酒庄,具有以下优势: 1.明星代言。雷盛(LEESON)品牌系列葡萄酒有幸邀请著名导演张纪中先生担任品牌代言人,为…

什么是天线OTA,怎么通过OTA数据评估产品射频环境情况

1.1 验证项目 产品的器件布局、走线是否合理、电源输入输出设计、纹波控制,铺地回流设计等是否合理. 通过验证产品的天线OTA_TIS项目来作为评估当前的设计是否合理之一,重点验证低频部分,如Band8段数据. 1.2 什么是天线OTA 是指某无线产品…

Vue3使用的Compostion Api和Vue2使用的Options Api有什么不同?

我们介绍Compostion Api和Options Api的区别之前,先来说一下为什么会推出来Composition Api,解决了什么问题? Vue2开发项目使用Options Api存在的问题 代码的可读性和维护性随着组件的变大业务的增多而变得差代码的共享和重用性存在缺点不支…

【Linux】进程查看|fork函数|进程状态

🦄 个人主页——🎐开着拖拉机回家_Linux,大数据运维-CSDN博客 🎐✨🍁 🪁🍁🪁🍁🪁🍁🪁🍁 🪁🍁🪁&am…

H.264宏块(Macroblock)概念(运动估计、变换编码、环路滤波)

参考文章:音视频高手课系列5-h264编码基础(宏块原理) 参考文章:切片slice与宏块,运动矢量 文章目录 使用videoEye分析视频宏块示例H.264宏块概念1. 宏块的定义2. 运动估计3. 变换编码4. 环路滤波5. 注意:宏块的概念既适用于帧内编…

基于Java Swing的图书管理系统

一、项目总体架构 本项目基于Java Swing框架,数据库采用的是MySQL。项目文件夹如下: 二、项目截图 1.登录和注册界面 2.用户界面 3.管理员管理图书类别 4.管理员管理书籍 5.管理员管理用户 项目总体包括源代码和课程论文,需要源码的…

Go语言实现KV存储系统:前言

文章目录 前言前提条件持久索引并发总结 前言 你好,我是醉墨居士,最近想做一些存储方面的东西玩玩,我第一时间就想到了能不能自己开发一个保存键值对的存储系统 我找了些资料,准备使用Go语言实现一下,想着有想法咱就…

通过MobaXterm远程连接Anolis

目录 前言: 一.设置ip 二.远程连接 前言: 小编已经阐述了如何安装Anolis系统,如果有不了解的小伙伴可以查看这一篇博客Anolis安装 这篇博客将会讲述如何远程连接Anolis系统。各位看官拿好板凳! 一.设置ip 打开网卡所在位…

西门子PLC通过PROFINET协议与多功能电表通讯

西门子PLC通过PROFINET协议与多功能电表通讯 项目要求 西门子S71200PLC需要通过PROFINET协议和多功能电表通讯,读取线电压、相电压、线电流、相电流、有功功率、无功功率等参数。 项目实施 采用网关NET90-PN-MBT(以下简称“网关”)&#…

Java开发框架和中间件面试题(9)

102.你了解秒杀吗?怎么设计? 1.设计难点:并发量大,应用,数据库都承受不了。另外难控制超卖。 2.设计要点: 将请求尽量拦截在系统上游html尽量静态化,部署到cdn上面。按钮及时设置为不可用&…

【Java面试题】redis的过期策略有哪些

redis通过设置过期时间来控制键值对的存活时长,过期时间可以通过expire , pexpire expireat , pexpireat 等命令设置,String 类型数据可以通过setex命令设置过期时间。 以下介绍三种redis的过期策略: 1. 定时删除 在设置键值对的过期时…

数据库概念学习

1. mysql默认的事物级别 MySQL 默认的隔离级别是可重复读(REPEATABLE READ)。 PostgreSQL 中,默认的隔离级别是读已提交(READ COMMITTED) 可重复读隔离级别是 MySQL 的默认隔离级别,它具有以下特点&#x…

Spring Data 灵活查询的三种方式

在页面中展示列表数据时,通常需要根据用户输入的不同的查询条件返回不同的查询结果,传统的方式往往采用手动编写原始sql拼接where条件的方式,这种方式并不安全,容易存在sql注入漏洞。 本文介绍用SpringDataJpa实现灵活查询的方式…

C# 委托(Delegate)

C# 委托(Delegate) C# 委托(Delegate)声明委托(Delegate)实例化委托(Delegate)委托的多播(Multicasting of a Delegate)委托(Delegate&#xff09…