vuex的数据定义(store.js)
import Vue from "vue";
import Vuex from "./vuex.js";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
counter: 0
},
mutations: {
add(state, payload) {
console.log('add payload', payload);
state.counter += payload;
}
},
actions: {
add({ commit }) {
setTimeout(() => {
commit("add", 2)
}, 1000);
}
},
getters: {
doubleCounter(state) {
return state.counter * 2;
}
}
});
源码实现
- 实现install方法用于vue插件加载
let Vue;
const install = function(_Vue) {
Vue = _Vue;
Vue.mixin({
beforeCreate() {
if (this.$options.store) {
Vue.prototype.$store = this.$options.store;
}
}
})
}
- 实现Store类进行数据劫持监听和事件操作
class Store {
constructor(options) {
const { mutations, actions, getters, state } = options;
this._mutations = mutations;
this._actions = actions;
this._getters = getters;
const computed = this.setGetters();
this.commit = this.commit.bind(this);
this.dispatch = this.dispatch.bind(this);
this._vm = new Vue({
data: {
$$state: state
},
computed
})
}
get state() {
return this._vm.$data.$$state;
}
set state(v) {
console.error('please use replace state to reset state')
}
commit(type, payload) {
const entry = this._mutations[type];
if (entry) entry(this.state, payload);
}
dispatch(type, payload) {
const entry = this._actions[type];
if (entry) entry(this, payload);
}
setGetters() {
this.getters = {};
const computed = {};
const store = this;
Object.keys(this._getters).forEach(key => {
const fn = store._getters[key];
computed[key] = function() {
return fn(store.state);
}
Object.defineProperty(store.getters, key, {
get: () => store._vm[key]
})
})
return computed;
}
}
- 导出当前实例
export default {
Store,
install
}
在页面中使用vuex
- 导入vuex实例
- 加载实例到vue
- 在vue组件中进行使用
import store from './store.js'
new Vue({
store,
render: h => h(App)
}).$mount('#app')
vue组件中使用
<template>
<div class="home">
<h1>This is an home page {{ $store.state.counter }}</h1>
<h1>vuex getters{{ $store.getters.doubleCounter }}</h1>
<button @click="$store.commit('add', 1)">add counter num</button>
<button @click="$store.dispatch('add')">dispatch add counter num </button>
</div>
</template>
<script>
export default {
name: "home",
components: {
},
created() {
setTimeout(() => {
},2000)
}
}
</script>
结语
- 以上代码实现了vuex的核心概念,帮我们了解到了为什么vuex的数据是响应式的
- 让我们深入的理解了vuex的api及其功能点
- 如还想对vuex进行更深层次的研究请前往官方 vuex github 源码进行查看