美文网首页
vue(vue-router&&vuex)全家桶源码实现(2)

vue(vue-router&&vuex)全家桶源码实现(2)

作者: 微_______凉 | 来源:发表于2020-07-04 15:48 被阅读0次

    vuex

    vuex的理念是 集中式的状态管理,(统一管理),并且变化可预测。
    底层依然是vue的数据响应式。
    基础知识
    state, action,mutation,store
    核心步骤
    1.实现vuex插件,并全局可获取
    2.声明,注册Store类
    3.响应式state属性

    • commit()可以修改state
    • dispatch()可以执行异步方法,再调用commit, 所以会返回一个promise

    vuex源码实现

    kstore/kvuex.js

    // 实现插件 挂载$store
    // 声明store 类 
        // 响应式state
        // commit 可以修改state
        // dispatch 可以调用action
        //实现getters getters 返回的是对应函数的执行结果
    let KVue
    
    class Store{
        constructor(options){
            console.log('options', options)
            //响应式的state
            // 方式一 借vue的data  因为data是响应式的,然后赋值给state
            this.state = new KVue({
                data:options.state
            })
            this._vm = new KVue({
                data:{  
                    $$state:options.state
                }
            })
            this._mutations = options.mutations
            this._actions = options.actions;
            this._getters = options.getters
            //绑定this到store
            const store = this;
            // 还是bind简单粗暴 
            // this.commit = this.commit.bind(store)
            //vuex官方 commit 与action 源码实现
            const {commit, action}= this;
            this.commit = function bindCommit(type, payload){
                commit.call(store, type, payload)
            }
            this.action = function bindAction(type, payload){
               return action.call(store, type, payload)
            }
            for(const k in options.getters){
                // this.getters[k] = options.getters[k](store.state)
                Object.defineProperty(this._getters, k, 
                    {
                    get(){
                        return options.getters[k](store.state)}
                    }
                )
            }
        }
        // get state(){
        //     return this._vm._data.$$state
        // }
        // set state(val){
        //     console.error('please use replaceState to reste state');
        // }
        // commit ({type, payload})
        // 执行mutaition 更改state
        commit(type, payload){
            let entry = this._mutations[type]
            if(!entry) {
                console.error('unknowe commit type');
                return
            }
            entry(this.state, payload)
        }
        dispatch(type, payload){
            let entry = this._actions[type]
            if(!entry){
                console.error('unknowe action type');
                return
            }
            return entry(this, payload)
        }
    }
    
    function install(Vue){
        KVue = Vue
        KVue.mixin({
            beforeCreate(){
                if(this.$options.store){
                    Vue.prototype.$store = this.$options.store
                }
            }
        })
    }
    export default {Store, install}
    

    测试代码

    <p @click="$store.commit('add')">counter :{{$store.state.counter}}</p>
    <p @click="$store.dispatch('add')">async counter :{{$store.state.counter}}</p>
    <p>dbcounter: {{$store.getters.dbcouter}}</p>
    

    kstore/index

    import Vue from 'vue'
    import Vuex from './kvuex'
    Vue.use(Vuex)
    export default new Vuex.Store({
      state: {
        counter: 1
      },
      mutations: {
        // state 哪来的 怎么实现响应式
        add(state){
          state.counter++
        }
      },
      actions: {
        add({commit}){
          setTimeout(()=>{
            commit('add')
          }, 1000)
        }
      },
      getters:{
        dbcouter: state=>{
          return state.counter*2
        }
        // dbcouter: state.counter*2
      },
      modules: {
      }
    })
    

    这两部分的学习让我对vue的响应式原理理解更深入了些,也更明白了MVVM框架为什么是数据驱动视图。
    好记性不如烂笔头,记录一下。

    相关文章

      网友评论

          本文标题:vue(vue-router&&vuex)全家桶源码实现(2)

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