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); }; }