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

相关推荐
uhakadotcom2 小时前
视频直播与视频点播:基础知识与应用场景
后端·面试·架构
范文杰2 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪3 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪3 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy3 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom4 小时前
快速开始使用 n8n
后端·面试·github
uhakadotcom4 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom4 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom4 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom4 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试