美文网首页
vuex源码解析(2.3.1)

vuex源码解析(2.3.1)

作者: susu一口酥 | 来源:发表于2021-08-05 15:07 被阅读0次

在网上有找到一些关于vuex源码分析的文章,有的写的很不错,挺详细的。但是在阅读的过程中还是发现很多地方不理解,所以搭建了环境调试,把不明白的地方逐个解决,这里把遇到的困惑记录并分享。

vuex是如何注册到全局,并通过this.$store使用的

//入口文件store.js
//在store的入口文件中,引入vue
import Vue from 'vue';
//在入口文件中引入自己手写 vuex
import Vuex from '../vuex';
//关键在于这个步骤,vue.use方法调用的时候触发Vuex实例中的install方法
Vue.use(Vuex);

//vuex.js文件
//所以在Vuex的实例中必须对外输出install方法
export default {
  install
}


//全局保存下Vue
let Vue
//定义下install方法
//调用时候会传入Vue实例
const install = (_Vue) => {
    //判断如果全局保存的Vue已经存在,还重新注册则抛出异常
    if(Vue){
      console.error('[vuex] already installed. Vue.use(Vuex) should be called only once.')
    return;
    }
   //把vue实例赋值给全局
  Vue = _vue;
  //调用混入方法,把$store注册到Vue实例
  privateMethods.applyMixin(_Vue);
}
//定义初始化方法(这边有点坑,这个方法不能用箭头函数,会影响this指向)
const vuexInit = function(){
  //拿到当前组件实例的配置信息
  const options = this.$options;
  //如果配置信息里有store则,把store赋值给this.$store
  if(options.store){
    this.$store = options.store;
  }
//如果当前没有store,但是父实例注册了$store,则把父实例的$store赋值给当前组件实例
  else if(options.parent && options.parent.$store){
    this.$store = this.$parent.$store;
  }
}
//之前我有个疑问,第一个options.store哪里来的。再看次配置信息才发现,是在main.js中初始化vue实例中给到的
//new Vue({el : '#app',store})
//定义PrivateMethods类,把需要用到的方法放在这里
class PrivateMethods {
  static applyMixin(vue){
    //获取vue版本号
    const version = vue.version.split('.')[0];
    //如果版本大于1
    if(version > 1){
      const usesInit = Vue.config._lifecycleHooks.indexOf('init') > -1;
    // 判断生命周期中是否有Init,有则把vuexInit放在Init中执行,如果没有则放在beforeCreate中执行
      vue.mixin(usesInit ? {init : vuexInit} : {beforeCreate : vuexInit});
    }
  }
}

增加Store类对外输出

//文件vuex.js
//对外输出Store类
export default {
  Store,
  install
}
class Store{
   //构造器中接收一个配置对象
  constructor(options = {}){
    //判断缓存的Vue实例是否存在
    if(!Vue){
      throw new Error(`must call Vue.use(Vuex) before creating a store instance.`);
    }
    //判断浏览器是否支持Promise,否则报错
    //由于dispatch要用到promise实现,所以对promise依赖
    if(typeof Promise === 'undefind'){
      throw new Error(`vuex requires a Promise polyfill in this browser.`);
    }
  }
}

//这样就可以在vuex.js配置文件中这么写了
export default new Vuex.Store({})

$store.state和严格模式实现

//vuex.js文件中
class Store{
  constructor(options={}){
    //获取严格模式配置,默认值为flase
    const {strict = false} = options;
    //获取配置的state信息
    let {state = {}} = options;
    //如果state为函数,则state为state函数返回值
    if(typeof state === 'function'){
      state = state();
    }
    //初始化state方法
    privateMethods.resetStoreVM(this,state);
  }
  //增加获取 state方法
  get state(){
    //_vm是构造的vue实例赋值在store上
    //_data是通过vue实例获取data的方式
    return this._vm._data.$$state 
  }
  //增加修改state方法
  //不允许直接赋值或者修改state
  set state(){
    throw new Error(`Use store.replaceState() to explicit replace store state.`)
  }
}

//在私有方法中增加初始化state方法
class PrivateMethods{
  //参数命名都比较明显,就不要解释了
  resetStoreVM(store,state,hot){
    //获取旧的挂载实例
    const oldVm = store._vm;
    //利用vue实例,实现state
    store._vm = new Vue({
      data : {
          $$state : state
      }
    } 
    //如果定义了严格模式
    if(store.strict){
      //执行严格模式方法
      this.enableStrictMode(store);
    }
    //如果存在旧的_vm实例则销毁
    if(oldVm){
      Vue.nextTick(()=> oldVm.$destory());
    }
  }
  //使用严格模式
  enableStrictMode(store){
    //使用$watch api监控store实例中$$state变化
     //当前指向是vue实例,所以不能用箭头函数
    store._vm.$watch(function(){
      //监控$$state
      return this._data.$$state;
    },()=>{
        //如果不是通过commit修改state值则抛出异常
        if(!store._committing){
          throw new Error(`Do not mutate vuex store state outside mutation handlers.`);
        }
    },{
    //深度监听,true
    deep : true,
    //监听子组件改变父组件 (vue1.0配置)
    sync:true
    })
  }
}

$store.commit实现

//期待整理

$store.dispatch实现

//期待整理

$store.subscribe实现

//期待整理

相关文章

  • vuex源码解析(2.3.1)

    在网上有找到一些关于vuex源码分析的文章,有的写的很不错,挺详细的。但是在阅读的过程中还是发现很多地方不理解,所...

  • Android2.3.1源码编译简略版

    Android2.3.1源码编译 编译2.3.1源码,用于学习老罗的《Android系统源码解析》 安装虚拟机 A...

  • 关于一些Vue的文章。(1)

    原文链接我的blog,欢迎STAR。 今天分享的一篇文章是关于vuex的源码解析的,链接vuex源码解析,在现在所...

  • Vuex源码解析

    写在前面 因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,这几个月花了些时间研究学习了一下Vue...

  • VUEX源码解析

    /plugins/devtool.js 浏览器开发者工具支持监控VueX /plugins/logger.js r...

  • Vuex源码解析

    手写vuex核心代码 vuex基本用法 分析 我们是通过new Vuex.store(option)获得一个sto...

  • Vuex 2.0 学习笔记(二):源码阅读

    上一章总结了 Vuex 的框架原理,这一章我们将从 Vuex 的入口文件开始,分步骤阅读和解析源码。由于 Vuex...

  • Vuex源码分析

    Vuex 源码学习 注释 源码目录 Vuex 核心 API: 插件安装 引入了 src/index.js 暴露的对...

  • ios三方库解析

    YYCache 源码解析 YTKNetwork 源码解析 MJRefresh 源码解析 VVeboTableVie...

  • iOS 一些框架源码解析

    YYCache 源码解析 YTKNetwork源码解析 MJRefresh 源码解析 VVeboTableView...

网友评论

      本文标题:vuex源码解析(2.3.1)

      本文链接:https://www.haomeiwen.com/subject/ofdmvltx.html