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

相关推荐
Suppose1 小时前
[Vue]template相关
vue.js
cnsxjean2 小时前
Vue教程|搭建vue项目|Vue-CLI2.x 模板脚手架
javascript·vue.js·ui·前端框架·npm
web组态软件2 小时前
BY组态-低代码web可视化组件
前端·低代码
react_in2 小时前
webpack 题目
前端·webpack
MarisolHu2 小时前
前端学习笔记-Vue篇-02
前端·vue.js·笔记·学习
学前端的小朱2 小时前
Webpack的基础配置
前端·webpack·node.js
小周同学_丶3 小时前
解决el-select数据量过大的3种方法
前端·vue.js·elementui
先知demons4 小时前
uniapp开发微信小程序笔记10-触底加载
前端·笔记·微信小程序·小程序·uni-app
每一天,每一步4 小时前
react antd不在form表单中提交表单数据,而是点查询按钮时才将form表单数据和其他查询条件一起触发一次查询,避免重复触发请求
前端·javascript·react.js
NoneCoder4 小时前
HTML5系列(9)-- Web Components
前端·html·html5