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