彦祖,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等等...

相关推荐
BJ-Giser25 分钟前
Cesium 基于EZ-Tree的植被效果
前端·可视化·cesium
王码码20351 小时前
Flutter for OpenHarmony:Flutter 三方库 algoliasearch 毫秒级云端搜索体验(云原生搜索引擎)
android·前端·git·flutter·搜索引擎·云原生·harmonyos
发现一只大呆瓜1 小时前
深入浅出 AST:解密 Vite、Babel编译的底层“黑盒”
前端·面试·vite
天天鸭2 小时前
前端仔写了个 AI Agent,才发现大模型只干了 10% 的活
前端·python·ai编程
发现一只大呆瓜2 小时前
前端模块化:CommonJS、AMD、ES Module三大规范全解析
前端·面试·vite
IT_陈寒2 小时前
一文搞懂JavaScript的核心概念
前端·人工智能·后端
IT_陈寒2 小时前
Java开发者必看!5个提升开发效率的隐藏技巧,你用过几个?
前端·人工智能·后端
前端Hardy2 小时前
Wails v3 正式发布:用 Go 写桌面应用,体积仅 12MB,性能飙升 40%!
前端·javascript·go
Laurence2 小时前
Qt 前后端通信(QWebChannel Js / C++ 互操作):原理、示例、步骤解说
前端·javascript·c++·后端·交互·qwebchannel·互操作
Pu_Nine_92 小时前
JavaScript 字符串与数组核心方法详解
前端·javascript·ecmascript