Skip to content
霞露小伙 — HfWang
On this page

学习 vuex

vuex 使用

js
// src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
export default new Vuex.Store({
  state: {
    a: 1,
    b: 2
  },
  getters: {
    doubleA(state) {
      return state.a * 2
    }
  },
  mutations: {
    changeB(state) {
      state.b ++
    },
    changeA(state, num = 2) {
      state.a += num
    }
  },
  actions: {

  }
})
js
// src/main.js
import Vue from 'vue'
import App from './App'
import store from './store'

new Vue({
  el: '#root',
  store, // 通过 options 传参传入 store 对象
  render: (h) => h(App),
})

先简单分析下, vuex 默认导出的是一个对象

Vue.use(Vuex) 说明 Vuex 对象里面至少有一个 install 方法

而后面又通过 new Vuex.Store({ .... }) 实例化出一个 store,

所以 vuex 导出的对象至少是这样的:

js
class Store {
  constructor(options) {
    // ...
  }
  // ....
}

function install(Vue, options) {
  // ...
}

export default {
  install,
  Store,
}

ok, 简单分析之后我们来开始看源码

实现 mini-vuex

js
let Vue

function install(_Vue) {
  Vue = _Vue
  Vue.mixin({
    beforeCreated() {
      if (this.$options?.store) {
        // root
        this.$store = this.$options.store
      } else {
        this.$store = this.$parent?.$store
      }
    },
  })
}

class Store {
  constructor(options) {
    const { 
      state = {}, 
      getters = {}, 
      mutations = {}, 
      actions = {}, 
    } = options

    this.vm = new Vue({
      data: {
        state,
      },
    })

    this.getters = {}
    Object.keys(getters).forEach((getterName) => {
      Object.defineProperty(this.getters, {
        get: () => {
          return this.getters[getterName](this.state)
        },
      })
    })

    this.mutations = {}
    this.actions = {}
    this.initMethods(options)
  }

  static initMethods = (options) => {
    const methods = ['mutations', 'actions']
    methods.forEach(method => {
      const targets = options[method] || {}
      Object.keys(targets).forEach((name) => {
        this[method][name] = (payload) => {
          targets[name](this.state, payload)
        }
      })
    })
  }

  get state() {
    return this.vm.state
  }

  commit(name, payload) {
    this.mutations[name](payload)
  }

  dispatch(name, payload) {
    this.actions[name](payload)
  }
}

export default {
  Store,
  install,
}

本站中引用到的其他资料,如有侵权,请联系本人删除