彦祖,vuex源码真的不学吗?

浅聊一下

最近看了一下vuex的源码,来和大家一起分享一下

VUEX

什么是vuex?其实vuex就是一个状态管理的设计模式。先来看看如何使用...

安装

安装 | Vuex (vuejs.org),安装教程双手奉上...

引入

  • 首先在main.js中引入并且use掉
js 复制代码
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import store from './store/index'
createApp(App)
.use(store)
.mount('#app')

vuex是vue生态的一个插件,所以我们需要使用安装并且use的一个操作让他生效,这意味着vuex中存在一个接口可以和vue连接,待会我们将来手写...

使用

  • 来到index.js
js 复制代码
import {createStore} from 'vuex'
const store = createStore({
    state(){
        return {
            count:1
        }
    },
    getters:{
        double(state){
            return state.count * 2
        }
    },
    mutations:{
        add(state){
            state.count++
        }
    },
    actions:{
        asyncAdd({ commit }){
            setTimeout(()=>{
                commit('add')
            },1000)
        }
    }
})
export default store

createStore接收一个对象,里面有state()、getters、mutations、actions。在state()中储存数据,getter中储存一些有返回值的方法或者计算属性,mutation中存放同步方法,actions中放异步方法...最后将store对象抛出

  • 来到APP.vue
js 复制代码
<template>
  <div>
    {{count}}*2 = {{double}}
    <br>
    <button @click="add">add</button>
    <button @click="asyncAdd">asyncAdd</button>
  </div>
</template>

<script setup>
import {  computed } from 'vue';
//hooks编程
import { useStore } from 'vuex';

let store = useStore();
let count = computed(() => store.state.count);
let double = computed(() => store.getters.double);

function add(){
  store.commit('add')
}

function asyncAdd(){
  store.dispatch('asyncAdd')
}
</script>

<style lang="css" scoped>

</style>

先创建store实例,通过mutation中的方法通过commit引入,actions里的方法通过dispatch引入...

源码实现

主要实现store类,dispatch、commit、createStore、useStore

store

store是一个类

js 复制代码
class Store {
    constructor(options) {
        this.$options = options
        // 私有的
        // store.state.  proxy
        this._state = reactive({
            data:options.state()
        })
        this._mutations = options.mutations
        this._actions = options.actions
        this.getters = {}

        Object.keys(options.getters).forEach(name=>{
            const fn = options.getters[name]
            this.getters[name] = computed(()=>fn(this.state))
        })
    }
    get state() {
        //get
        return this._state.data
    }
    commit = (type,payload)=>{
        const entry = this._mutations[type]
        entry && entry(this.state,payload)
    }
    dispatch(type,payload) {
        const entry = this._actions[type]
        return entry && entry(this,payload)
    }
    install(app) {
        // 电台 发布者
        app.provide(STORE_KEY, this)// provide vue内置方法
    }
}
  • constructor(options): 构造函数接收一个options对象,该对象包含有关状态管理器的配置信息。
  • this._state: 使用Vue 3的reactive函数创建了一个响应式状态对象,它包含了应用的状态数据。状态数据初始化为options.state()的返回值。
  • this._mutationsthis._actions: 分别存储变更和异步操作的处理函数。
  • this.getters: 存储获取器(类似于计算属性)的对象。
  • get state(): 这是一个getter方法,用于获取状态数据。它简单地返回this._state.data
  • commit(type, payload):通过commit()来获取mutations中的方法,在mutations中查找以type为键名的方法,然后返回
  • dispatch(type, payload): 这是一个用于分发异步操作的方法。它会查找给定type的异步操作处理函数,并执行它。

你可以看到其实commitdispatch的代码是一样的,所以为什么说mutation处理同步,而actions处理异步呢?我了解到其实他们设计的初衷就是将同步和异步操作分开来,其实并没有什么大的区别...

  • install(app): 这个方法用于安装状态管理器到Vue应用中。它使用Vue 3的provide方法将STORE_KEY关联的值设置为当前Store实例,使得在应用的任何地方都可以通过依赖注入来访问该实例。这就是vuex和vue相连接的关键...

useStore && createStore

  • useStore
js 复制代码
const STORE_KEY = '__store__'
function useStore() {
    return inject(STORE_KEY)
}

在Vue 3中,为了在组件中使用全局状态管理器,需要使用一个名为inject的函数来访问它。但是每次在组件中都调用inject函数来获取全局状态管理器会显得有些繁琐。

为了简化这个过程,可以创建一个自定义的函数(例如useStore),该函数封装了inject函数的调用,使得在组件中获取全局状态管理器更加简单。

  • createStore
js 复制代码
function createStore(options) {
    return new Store(options)
}

效果

结尾

最近在学习vue的源码系列...之后会一直更新vue源码,从template到虚拟DOM等等...

相关推荐
pusheng202520 小时前
普晟传感2026年新春年会总结与分析
前端·javascript·html
谢尔登20 小时前
React19事件调度的设计思路
前端·javascript·react.js
Emma_Maria20 小时前
本地项目html和jquery,访问地址报跨域解决
前端·html·jquery
奋斗吧程序媛20 小时前
常用且好用的命令
前端·编辑器
2301_7965125220 小时前
【精通篇】打造React Native鸿蒙跨平台开发高级复合组件库开发系列:Lazyload 懒加载(懒加载的图片)
前端·javascript·react native·react.js·ecmascript·harmonyos
敲敲了个代码21 小时前
从N倍人力到1次修改:Vite Plugin Modular 如何拯救多产品前端维护困境
前端·javascript·面试·职场和发展·typescript·vite
Yff_world21 小时前
网络安全与 Web 基础笔记
前端·笔记·web安全
Sapphire~21 小时前
Vue3-19 hooks 前端数据和方法的封装
前端·vue3
浩宇软件开发21 小时前
基于OpenHarmony鸿蒙开发医院预约挂号系统(前端后端分离)
前端·华为·harmonyos
嘿是我呀21 小时前
【用npm安装node时报错“npm 无法加载文件”】
前端·npm·node.js