美文网首页
手写简单Vuex

手写简单Vuex

作者: Betterthanyougo | 来源:发表于2020-05-02 21:55 被阅读0次

Vuex

Vuex 集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以可预测的方式发生变化。

核心概念

state 状态、数据 mutations 更改状态的函数 actions 异步操作
store 包含以上概念的容器

状态 - state

state保存应用状态

export default new Vuex.Store({
 state: { counter:0 },
})

状态变更 - mutations

mutations用于修改状态,store.js

export default new Vuex.Store({
 mutations: {
   add(state) {
     state.counter++
} }
})

派生状态 - getters

从state派生出新状态,类似计算属性

 
export default new Vuex.Store({
  getters: {
doubleCounter(state) { // 计算剩余数量 return state.counter * 2;
} }
})

动作 - actions

添加业务逻辑,类似于controller

 
export default new Vuex.Store({
    actions: {
        add({ commit }) {
            setTimeout(() => {
commit('add')
}, 1000);
} }
})

vuex原理解析

任务分析

实现一个插件:声明Store类,挂载$store Store具体实现:
创建响应式的state,
保存mutations、actions和getters 实现commit根据用户传入type执行对应mutation
实现dispatch根据用户传入type执行对应action,
同时传递上下文 实现getters,按照getters定义对state做派生
初始化:Store声明、install实现

let Vue;
class Store {
  constructor(options = {}) {
    this._vm = new Vue({
      data: {
        $$state:options.state
      }
}); }
  get state() {
    return this._vm._data.$$state
}
  set state(v) {
    console.error('please use replaceState to reset state');
} }
function install(_Vue) {
  Vue = _Vue;
  Vue.mixin({
    beforeCreate() {
      if (this.$options.store) {
        Vue.prototype.$store = this.$options.store;
} }
}); }
export default { Store, install };

实现commit:根据用户传入type获取并执行对应mutation

class Store {
 constructor(options = {}) {
// 保存用户配置的mutations选项
   this._mutations = options.mutations || {}
 }
commit(type, payload) {
// 获取type对应的mutation
const entry = this._mutations[type]
   if (!entry) {
     console.error(`unknown mutation type: ${type}`);
     return
}
// 指定上下文为Store实例
// 传递state给mutation entry(this.state, payload);
} }

实现actions:根据用户传入type获取并执行对应action

class Store {
  constructor(options = {}) {
// 保存用户编写的actions选项 this._actions = options.actions || {}
// 绑定commit上下文否则action中调用commit时可能出问题!! // 同时也把action绑了,因为action可以互调
const store = this
const {commit, action} = store
    this.commit = function boundCommit(type, payload) {
      commit.call(store, type, payload)
    }
    this.action = function boundAction(type, payload) {
      return action.call(store, type, payload)
    }
}
dispatch(type, payload) {
// 获取用户编写的type对应的action const entry = this._actions[type]
    if (!entry) {
      console.error(`unknown action type: ${type}`); 
return
}
// 异步结果处理常常需要返回Promise
    return entry(this, payload);
  }
}

实现getter,state的计算属性

let Vue;
class Store {
  constructor(options) {
    // 定义响应式的state
    // this.$store.state.xx
    // 借鸡生蛋
    let computed={}
    Object.keys(options.getters).forEach(function (key) { 
      computed[key]=function () {
        return options.getters[key](options.state)
      } 
    })
   console.log(computed)
 
    this._vm = new Vue({
      data: {
        $$state: options.state
      },
      computed:computed
    })
    
    this._mutations = options.mutations
    this._actions = options.actions

    // 绑定this指向
    this.commit = this.commit.bind(this)
    this.dispatch = this.dispatch.bind(this)
  }
  get getters() {
    return this._vm
  }
  // 只读
  get state() {
    return this._vm._data.$$state
  }

  set state(val) {
    console.error('不能直接赋值呀,请换别的方式!!天王盖地虎!!');
    
  }
  
  // 实现commit方法,可以修改state
  commit(type, payload) {
    // 拿出mutations中的处理函数执行它
    const entry = this._mutations[type]
    if (!entry) {
      console.error('未知mutaion类型');
      return
    }

    entry(this.state, payload)
  }

  dispatch(type, payload) {
    const entry = this._actions[type]

    if (!entry) {
      console.error('未知action类型');
      return
    }

    // 上下文可以传递当前store实例进去即可
    entry(this, payload)
  }
}

function install(_Vue){
  Vue = _Vue

  // 混入store实例
  Vue.mixin({
    beforeCreate() {
      if (this.$options.store) {
        Vue.prototype.$store = this.$options.store
      }
    }
  })
}

// { Store, install }相当于Vuex
// 它必须实现install方法
export default { Store, install }

相关文章

  • 手写简单Vuex

    Vuex Vuex 集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以可预测的方式发生变化。 核心概念 ...

  • 手写简单Vuex

    手写 vuex 插件固定写法 混入 创建 Store 由于需要使用 new Vuex.Store 来创建,所以 V...

  • Vuex源码解析

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

  • 手写Vuex源码

    Vuex源码实现 1. Vuex核心概念State,Getters,Mutations, Actions, Mod...

  • 手写一个Vuex(一)

    手写一个Vuex,命名为myVuex,替换Vuex的引入,其他使用方法不变。如下内容: 首先,先创建myVuex文...

  • Vuex(三) —— 纯手写一个超简单的Vuex

    目录 分析Vuex的功能 下载模板 分析模块结构 实现install函数 实现Store类 替换vuex 前面学了...

  • 通过一个简单实例了解vuex

    简单说明 什么是vuex,vuex怎么使用,什么场景下适合使用vuex, vuex 文档中都有介绍。看完文档之后,...

  • 前端数据流之vuex

    从前整理过vuex,这篇是补充 最简单的vuex 多个组件共享状态时的vuex 初始化 vue create vu...

  • vue状态管理vuex

    一、vuex的简单介绍 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,简单的来说作用是:可以简单...

  • vuex的简单应用01

    二、简单的从store中取值 三、简单的改变vuex中的值 三.1 简单的改变vuex中的值--传递一个参数 三....

网友评论

      本文标题:手写简单Vuex

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