vuex的用法

html

 <div id="app">    弟弟的年龄:{{$store.state.age}}    哥哥的年龄:{{$store.getters.getAge}}    <button @click="$store.commit('changeAge',5)">五年后</button>    <button @click="$store.dispatch('changeAge',10)">十年后</button>  </div>

store

import Vue from "vue";import Vuex from "vuex";Vue.use(Vuex);export default new Vuex.Store({//状态  state: {    age: 18  }, //相当于计算属性  getters: {    getAge(state) {      return state.age + 10;    }  },  //批改状态的办法  mutations: {    changeAge(state, payload) {      state.age = state.age + payload;    }  },  //解决mutations只有同步没有异步  actions: {    changeAge({ commit }, payload) {      setTimeout(() => {        commit("changeAge", payload);      },1000);    }  }});

main

import store from "./store";new Vue({  router,  store,  render: h => h(App)}).$mount("#app");

简略的实现

vuex/index

vuex/index 作为总进口 应用两种模式导出
export {} ===> import {Store} from 'vuex'
export default ===> import Store from 'vuex'

import { Store, install } from "./store";export { Store, install };export default {  Store,  install,};
vuex/store

vuex/store.js这个文件为了不便将install办法和Store类写在一起

install

install办法:将new Vue({store}) 中的store利用Vue的minxin办法通过递归遍历使所有组件都能够用$store来获取到

let Vue;export const install = (_Vue) => {  Vue = _Vue;  Vue.mixin({    beforeCreate() {      if (this.$options.store) {        this.$store = this.$options.store;      } else if (this.$options.parent && this.$options.parent.$options.store) {        this.$store = this.$options.parent.$options.store;      }    },  });};

Store

state 办法

实现了install办法之后咱们发现这样实现state更为不便一些

export class Store {  constructor(options) {    this.state = options.state    }}

下面这种能够获取到 然而并没有将state进行双向数据绑定,state扭转视图并不会产生扭转,下面的install办法能够拿到全局的Vue,这样咱们能够利用Vue中的observe来将state中的数据增加get和set办法

export class Store {  constructor(options) {    let state = options.state;    this._vm = new Vue({      data: {      //$$为外部办法 不挂载在实例上        $$state: state,      },    });  }  //取state这个值得时候会触发这个办法  get state() {    return this._vm._data.$$state;  }}
公共办法forEach的实现
export const forEach = (obj, fn) => {  Object.keys(obj).forEach((v) => fn(v, obj[v]));};

应用办法

forEach({ name: "孟", val: "01" }, (key, fn) => {  console.log(key, fn);});//传入一个对象,获取到对象的每一个key和val
getters办法的实现

getters是一个对象 应用的时候$store.getters.getAge,是getAge执行后的后果

    this.getters = {};    let computed = {};    forEach(options.getters, (key, fn) => {    //每次其余数据变动刷新页面都会进行没必要的获取getters中的数据,computed具备缓存的成果 数据不产生扭转就不会触发相应的办法      computed[key] = () => {        return fn(this.state);      };      //给getter进行双向数据绑定      Object.defineProperty(this.getters, key, {      //computed是挂载在实例上的属性        get: () => this._vm[key],      });    });    this._vm = new Vue({      data: {        $$state: state,      },      computed,    });
mutations实现

mutations是根据公布订阅模式先将每一个函数贮存在事件池中,而后通过用户的一个派发动作使对应的事件池中的函数执行

 class Store {  constructor(options) {  this.mutations = {};    forEach(options.mutations, (key, fn) => {      this.mutations[key] = (payload) => fn(this.state,payload);    });   }     commit = (key, payload) => {    this.mutations[key](payload);  };  }    
actions的实现
 class Store {  constructor(options) { this.actions = {};    forEach(options.actions, (key, fn) => {      this.actions[key] = (payload) => fn(this, payload);    }); dispatch = (key, payload) => {    this.actions[key](payload);  };  }