vuex01---vuex实现原理

vuex的设计思想:单向数据流的设计思想(数据可控,错误好追踪)

在组件中不能修改state中的数据,只能通过commit mutation来修改数据,或者dispatch action,在action中再commit mutation来修改数据

vuex任务分析: 

***.vue----------------------------------------------

<div>{{$store.state.count}}</div>     

this.$store.dispatch("asyncIncrement", request2)

main.js中-------------------------------------------

import store from './store'

new Vue({    
  store,(在此挂载一下的目的就是供上面.vue组件中可以通过$store直接去访问)$store也是通过prototype的方式进行挂载的
  render: h => h(App)
}).$mount('#app')

store.js------------------------------------------------(vuex装进来)

import Vue from "vue"
import Vuex from "vuex"
Vue.use(Vuex);//use方法调用了install方法
export default new Vuex.Store({//创建store实例
    state:{count:0}, //存数据的
    mutations:{       //改数据的
        increment(state){
            state.count += 1
        }
    },
    getters:{        //类似计算属性,对state进行加工
        left(state){
            return 1-state.count
        }
    },
    actions:{       //异步方法可写入,通过commit修改mutation
        asyncIncrement({getters,commit}){  //参数能拿到getters,commit等,是因为vuex里封装的方法将Store的实例当参数传出
            return new Promise((resolve,reject) => {
                setTimeout(() => {
                        commit("increment");
                        resolve();
                        return;
                },1000);
            })
        }
    }
})

 任务分析----------------------------------

·实现插件:$store(store的实例)挂载

·实现Store类:解析vuex的配置,持有$state,实现dispatch,commit,getters核心概念:

·借助vue实现数据的响应式

vuex.js---------------------------------------实现代码
let Vue;
class Store {  //(通过store.js的vuex实例(Vuex.Store)可知,要创建一个Store类,实例中传了一个参数包含state,mutation,action等,所以Store类重要对其进行解析)
    //持有state,并使其响应化
    //实现commit和dispatch两个方法
    constructor(options){
       //解析实例中传入的数据
        this.state = new Vue({data:options.state}); //因为state要实现数据响应式,   //this.state是Vue实例,访问this.state.count就为响应式的count
        this.mutations = options.mutations;
        this.actions = options.actions;

        //bind this----- commit和dispatch方法中在调用时  this的指向会出现问题(出现函数中调用函数的情况下,this指向会出现问题)
        this.commit = this.commit.bind(this);
        this.dispatch = thid.dispatch.bind(this);//箭头函数
 
  options.getters && this.handleGetters(options.getters);
    }
 handleGetters(getters){
  this.getters = {};//定义this.getters
  //遍历getters选项,为this.getters定义property
  //属性名就是选项中的key,只需要定义get函数保证其只读性
  Object.keys(getters).forEach(key => {
    Object.defineProperty(this.getters,key,{
      get:() => {
        return getters[key](this.state)
      }
    })
  })
 }
    //实现commit:可修改state中的数据
    commit(type,arg){
        this.mutations[type](this.state,arg);//从mutations里拿到名字为type的方法,调用他,把state数据以及参数传给他
    }
    dispatch(type,arg){
        return this.actions[type](this,arg); //从actions里拿到名字为type的方法,传入的参数为this为当前实例,所以actions中的方法可以({commit,state})
    }
}
//声明插件的install方法(Vue.use()用到install方法,规定)
function install(_Vue){//-----vue的插件必须实现install方法--规定
    Vue = _Vue;           //_Vue是形参:Vue的构造函数,use会把它传进来的
    Vue.mixin({  //混入
        beforeCreate(){
            //this指的是组件实例
            if(this.$options.store){ //vue实例传进去的store,即new Vue({store})
  
                Vue.prototype.$store = this.$options.store;//use先执行,实例后创建,所以必须写入到mixin  不然此实例不存在
            }
        }
    })
}

//导出vuex
export default {Store,install}

 

vuex里有个类叫store(绿框),能改数据的只有mutation;

vuex里要实现数据的响应式(因为组件中用到的数据,如果数据发生变化,界面要变更,所以数据必须是响应式的)--- 实现:vuex的构造函数初始化时做了响应式,所以与vue紧耦合,只能用在vue中;

 

原文地址:https://www.cnblogs.com/znLam/p/12852791.html