zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    openwrt 相关文章
    负载均衡相关文章
    Today's Progress
    Rodrigues formula is beautiful, but uneven to sine and cosine. (zz Berkeley's Page)
    Camera Calibration in detail
    Fundamental Matrix in Epipolar
    Camera Calibration's fx and fy do Cares in SLAM
    FilterEngine::apply
    FilterEngine 类解析——OpenCV图像滤波核心引擎(zz)
    gaussBlur
  • 原文地址:https://www.cnblogs.com/0915ty/p/14251551.html
Copyright © 2011-2022 走看看