欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vuex 的实现原理

程序员文章站 2022-04-02 21:14:04
...

vuex 的实现:

  1. 在vue项目中先安装vuex
  2. 利用vue的插件机制,使用Vue.use(vuex)时,会调用vuex的install方法,装载vuex
  3. 使用vue的mixin混入机制,在beforeCreate钩子函数前混入,全局注入store,让每一个组件和实例,都能访问到 $store,来实现组件间的状态共享

VueX 源码图解如下:
vuex 的实现原理

示例代码实现:
main.js

import Vue from 'vue'
import App from './App.vue'
import store from './store'

Vue.config.productionTip = false

new Vue({
  store,
  render: h => h(App),
}).$mount('#app')

store.js

import Vue from 'vue'

import Vuex, {Store} from './vuex'

Vue.use(Vuex);

const state = {
  count: 10,
  val: 2
}

const getters = {
  result(state, getters){
    return state.count * state.val;
  },
  result2(state, getters){
    return state.count / state.val;
  }
}

const mutations = {
  modify(state, value){
    state.count = value;
  }

}

const actions = {
  requestModifyCount(context, value){
    setTimeout(() => {
      context.commit('modify', value);
    }, 2000);
  }

}
// const store = new Vuex.Store({
const store = new Store({
  state,
  getters,
  mutations,
  actions
});

export default store;

vuex 文件下的 index.js

let Vue = null;

export default class Vuex{
  static install(_Vue){

    Vue = _Vue;

    // 混入,为了每一个组件和实例,都能访问到$store,前提是根实例配置了store
    Vue.mixin({
      beforeCreate(){
        if(this.$root.$options.store){
          this.$store = this.$root.$options.store;
        }
      }
    })
    
  }
}

export class Store{

  constructor({state, getters, mutations, actions}){
    this._state = state;
    this._getters = getters;
    this._mutations = mutations;
    this._actions = actions;

    // 转换实例将要使用的计算属性
    let obj = {};
    Object.entries(getters).forEach(([key, value])=>{
      obj[key] = ()=>{
        return value(state, obj);
      }
    })

    // 构建实例
    this._vm = new Vue({
      data: state,
      computed: obj
    });

    // 处理data,转为store.state
    this.state = this._vm.$data;

    // 构建getters
    this._handleGetters();  
    
  }

  _handleGetters(){
    //$store._vm.result    $store.getters.result
    this.getters = {};
    Object.keys(this._getters).forEach(key=>{
      
      Object.defineProperty(this.getters, key, {
        enumerable: true,
        configurable: true,
        get: ()=>{
          return this._vm[key];
        }
      });
    })
  }


  commit(name, payload){
    //调用插件,提醒开发者数据的变化流程
    this._mutations[name](this.state, payload);
  }


  dispatch(name, payload){
    // 使用promise做封装
    this._actions[name](this, payload);
  }
  
}

Vuex.Store = Store;

Vuex 应用场景:

  1. 多个视图依赖于同一个状态
  2. 来自不同视图的行为需要变更同一个状态