Vuex 原理

2019-12-13  本文已影响0人  Do_Du

1、Vue.use(Vuex):将Vuex 应用到Vue中

use是一个自定义插件,这个插件里有一个固定方法install(),这句话的意思是调用这个自定义插件install方法

2、export default new Vuex.Store({

Store:就是用来存储数据的,以及提供数据访问接口

3、模拟Vuex原理
在store - vuex.js 中
改变引入路径 如下:


image.png
// 自定义 vuex

var Vue // 设置全局对象Vue 存储下来vue对象

// 数据存储类
class Store {
  constructor(options) { // 构造函数;new 类Store会初始化构造函数; options即为new Vuex时传的state、mutations、actions等参数
    // state
    this.vm = new Vue({ // 实例化一个Vue对象,将 外面 Vuex的参数传进来
      data: {
        state: options.state // 将 Vuex的参数 state 传进来,为的是实现数据的监听
      }
    })

    // getters
    const getters = options.getters
    this.getters = {}
    Object.keys(getters).forEach(getterName => { // getterName是myNum
      Object.defineProperty(this.getters, getterName, { // es5 添加对象属性: 给this.getters添加 getterName的属性
        get: () => { // getterName 属性 添加查询方法get
          return getters[getterName](this.state) // getters[getterName]:拿到方法 myNum,传入参数(this.state)
        }
      })
    })

    // mutations 同步
    const mutations = options.mutations
    this.mutations = {}
    Object.keys(mutations).forEach(mutationName => {
      this.mutations[mutationName] = (params) => {
        mutations[mutationName](this.state, params)
      }
    })

    // actions 异步
    const actions = options.actions
    this.actions = {}
    Object.keys(actions).forEach(actionName => {
      this.actions[actionName] = (params) => { // this.actions[actionName]: 给当前对象this.actions 添加函数,函数名是actionName
        actions[actionName](this, params) // 真正执行的函数 是外面传进来的
      }
    })
  }
  dispatch(type, params) { // 异步增加
    this.actions[type](params)
  }
  commit = (type, params) => { // 同步增加 箭头函数 this不会变
    this.mutations[type](params)
  }
  get state() {
    return this.vm.state
  }
}

// 插件需要
const install = (v) => {
  // console.log(v)  // 打印出来这个v就是Vue对象
  Vue = v // 使用全局对象Vue存储下来

  // 这个插件的作用:需要在所有的组件中添加$store对象
  // 才能让所有的组件中使用this.$store.commit()调用方法
  // 所有的根组件和子组件中,跟组件是在main.js中引入store,子组件呢,子组件通过mixin方法找到

  Vue.mixin({ // Vue 提供的方法 混合,通过这个可以给每个子组件加上store属性
    beforeCreate() { // 组件初始化之前 添加生命周期
      // this: 当前实例对象,每个组件都有一个options - name : 组建的名字
      // 打印出 undefined 和 APP
      // undefined 是根组件,即 main.js
      console.log(this.$options.name)

      // 只有根节点有store 存在参数配置项且store存在 把根节点的store赋值给新命名的对象$store
      if (this.$options && this.$options.store) { // 判断当前是父节点 root
        this.$store = this.$options.store
      } else { // 判断当前是子节点 child 父节点存在 并且 父节点的$store对象存在 就赋值
        this.$store = this.$parent && this.$parent.$store
      }
    }
  })
}

export default { install, Store }
image.png

注意:
根组件是:main.js
默认情况下子组件是:App.vue

若给根组件main.js 加上name,则 this.$options.name 打印出 Root 和App

image.png image.png
上一篇下一篇

猜你喜欢

热点阅读