• Vuex的原理 (一、Vue.use(vuex)做了什么?)


    Vuex的原理 一

      针对vuex的版本 3.5.1
    
    • Vue.use(vuex)这个过程中vuex都做了什么?

    调用vuex的install方法,判断Vuex是否已经注册过了,注册过了就直接返回,这里使用的是单例模式。
    调用applyMixin(Vue)
    将初始化vuex的方法(vuexInit)混入到vue的beforeCreate生命周期中;
    将$store绑定到每个vue实例中。

    源码解读
    • 再看install方法之前,我们需要先了解一下vuex.use方法都做了什么,源码位置位于Vue源码项目中的 src/global-api/use.js

        Vue.use = function (plugin: Function | Object) {
            const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
            if (installedPlugins.indexOf(plugin) > -1) { // Vue检测是否已经注册过这个插件, 如果已经注册过就直接返回
              return this
            }
      
            // additional parameters
            const args = toArray(arguments, 1) // 把参数截取出来组成一个数组,后面需要作为apply的第二个参数传入,注意这里不要第一个参数,因为第一个参数是我们的插件,比如(vuex,vueRouter、elementui)等;
            args.unshift(this) // 把Vue作为第一个参数
            if (typeof plugin.install === 'function') {
              plugin.install.apply(plugin, args) // 如果插件有intall方法就直接调用他的install方法,并把args传入。
            } else if (typeof plugin === 'function') {
              plugin.apply(null, args)
            }
            installedPlugins.push(plugin)
            return this
          }
      
      • 接下来我们看Vuex的install方法,源码位置在Vuex的 src/store.js
        export function install (_Vue) {
          if (Vue && _Vue === Vue) { // 这里也是判断Vue是否已经注册过vuex了,如果注册过就直接返回,注意vuex是单例模式
            if (__DEV__) {
              console.error(
                '[vuex] already installed. Vue.use(Vuex) should be called only once.'
              )
            }
            return
          }
          Vue = _Vue
          applyMixin(Vue) // 调用applyMixin, 看下这个函数干了啥
        }
      
      • applyMixin 方法 源码位于 Vue的 src/mixin.js
       export default function (Vue) {
         const version = Number(Vue.version.split('.')[0]) // 获取vue的版本
      
         if (version >= 2) { // 如果版本大于等于2, 就在vue的beforeCreate中混入vuexInit函数, 接下来看一下vuexInit
           Vue.mixin({ beforeCreate: vuexInit })
         } else { // 这段代码可以不看, 针对vue低版本的vuex的处理
           // override init and inject vuex init procedure
           // for 1.x backwards compatibility.
           const _init = Vue.prototype._init
           Vue.prototype._init = function (options = {}) {
             options.init = options.init
               ? [vuexInit].concat(options.init)
               : vuexInit
             _init.call(this, options)
           }
         }
      
         /**
          * Vuex init hook, injected into each instances init hooks list.
          */
      
         function vuexInit () { // 当我们实例化vue的时候就会调用这个函数了。
           const options = this.$options // 获取vue的$options
           // store injection
           if (options.store) { // 判断options中是否存在store属性,这里就是我们在vue的main.js中实例化Vue时写的new Vue({store}).$mount('app')
             this.$store = typeof options.store === 'function'
               ? options.store()
               : options.store  // 将vuex绑定到Vue实例的$store属性上
           } else if (options.parent && options.parent.$store) { 
             /* 这里的代码的意思是,我们需要在任何Vue的组件中都能通过使用this.$store直接调用vuex,
             所以vuex给我们做了这个工作,如果当前组件的option没有store属性,
             就看他的父组件上有没有,直到拿到store,然后赋值给$store属性,
             这样我们就能在Vue的组件中使用this.$store了。*/
             this.$store = options.parent.$store
           }
         }
      

      总结 Vue.use(vuex)

         - 判断vue是否已经注册过vuex插件;
         - 将`vuexInit`函数混入到vue的beforeCreate生命周期中;
         - 实例化vue时,会在vue每个实例上添加$store属性,并将vuex的实例绑定到$store属性上。
      

    个人github地址 https://github.com/ComponentTY/vue-sourcecode/tree/master/vuex

  • 相关阅读:
    从零开始入门 K8s | 有状态应用编排
    OAM 深入解读:OAM 为云原生应用带来哪些价值?
    你不得不了解 Helm 3 中的 5 个关键新特性
    CNCF 公布 2020 年 TOC 选举结果 | 云原生生态周报 Vol. 36
    调度系统设计精要
    Spring的IOC容器第一辑
    JavaScript工作体系中不可或缺的函数
    教你五步制作精美的HTML时钟
    web前端vertical-align的作用及对象详解
    JavaScript中常见的10个BUG及其修复方法
  • 原文地址:https://www.cnblogs.com/0915ty/p/14251551.html
Copyright © 2020-2023  润新知