Introduction to the

In the last article, we implemented the core implementation of vue-Router in less than 80 lines of code, albeit with very low functionality. But it is enough to illustrate the core principles of vue-Router.

  • Vue-router, the core version, takes only 80 lines of code

Today we will continue to analyze the core principles and source code of Vuex, one of the vue family buckets. We also need less than 80 lines of code to achieve a simplified version of Vuex.

Vuex use

We won’t talk too much about the use of vuex. Through the vUE plug-in installation. Similar to vue-Router.

The core concepts in VUEX.

  • State: A single state tree that stores all application layer states in one object.
  • Mutations: The only way to change the store. Mutation is committed using the COMMIT method.
  • Actions: The action submitted is mutation. Contains the specific business logic.
  • Commit: Used to commit a mutation
  • Dispatch: Dispatches an action
  • Getters: state A derived state that can be used for secondary processing aggregation.

If some students are not familiar with vuEX, I strongly recommend that you read the document carefully.

  • Vuex document

Implementation of the core vuex.

The following code implements the above. Detailed comments are included in the code. If not clear, please compare with the use of VUEX.

lib/x-vuex.js

let Vue;

class Store {
  constructor(options) {
    const {
      state,
      mutations,
      actions,
      getters
    } = options;
    this.$options = options;

    // Use vUE for data response.
    this.state = new Vue({
      data: state
    });

    this.mutations = mutations;
    this.actions = actions;

    this.handleGetters(getters);
  }

  ** ** returns the result of mutations. * @param {String} type method name * @param {... Any} arg parameter */
  commit = (type, ... arg) = > {
    const fn = this.mutations[type];
    fn && fn(this.state, ... arg); }* @param {String} type method name * @param {... Any} arg parameter */
  dispatch = (type, ... arg) = > {
    const fn = this.actions[type];

    const ctx = {
      state: this.state,
      commit: this.commit,
      dispatch: this.dispatch,
      getters: this.getters }; fn && fn(ctx, ... arg); }* @param {Object} getters {add: state => {}} */
  handleGetters = (getters) = > {
    this.getters = {};

    // Use defineProperty to implement read-only attributes.
    / / the enclosing $options. Getters
    Object.keys(getters).forEach(fnName= > {
      const fn = getters[fnName];
      Object.defineProperty(this.getters, fnName, {
        get: (a)= > fn(this.state) }); }); }}* @param {Object} _Vue Vue constructor */
const install = _Vue= > {
  Vue = _Vue;

  Vue.mixin({
    beforeCreate() {
      if (this.$options.store) {
        Vue.prototype.$store = this.$options.store; }}}); };// Keep the same usage as vuex. Export the Store and Install objects.
// - new Vuex.Store()
// - Vue.use(Vuex)
export default {
  Store,
  install
};

Copy the code

other

  • As you can see from the above code, VUex is heavily dependent on Vue for data responsiveness. This means vuex can only be used with VUE.
  • Those familiar with Redux should know that redux is a function that doesn’t depend on any framework. It can be used in react or VUE.

Project code

demo