- 新创建一个class类实现Vuex基本功能
- 将store注入Vue实例和Vue组件中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<span>{{num}}</span>
<button @click='add'>增加1</button>
<button @click='asyncAdd'>异步增加1</button>
<Child />
</div>
</body>
<script src="./vue.js"></script>
<script>
// 实现Vuex
class Store {
constructor(options) {
this.vm = new Vue({ // 实例化一个Vue对象,将 外面 Vuex的参数传进来
data() {
return { state: options.state } // 将 Vuex的参数 state 传进来,为的是实现数据的监听
}
})
let getters = options.getters;
this.getters = {}
Object.keys(getters).forEach(getterName => {
Object.defineProperty(this.getters, getterName, {
get: () => {
return getters[getterName](this.vm.state)
}
})
})
let mutations = options.mutations;
this.mutations = {};
Object.keys(mutations).forEach(mutationName => {
this.mutations[mutationName] = (payload) => {
mutations[mutationName](this.state, payload)
}
})
let actions = options.actions;
this.actions = {};
Object.keys(actions).forEach(actionName => {
this.actions[actionName] = (payload) => {
actions[actionName].call(this, this, payload)
}
})
}
get state() {
return this.vm.state;
}
commit(mutationName, payload) {
this.mutations[mutationName](payload);
}
dispatch(actionName, payload) {
this.actions[actionName](payload);
}
}
// 实例化一个Vuex
let store = new Store({
state: { num: 1 },
getters: {
getNum: function (state) {
return state.num
}
},
mutations: {
add(state, payload) {
state.num = state.num + payload;
}
},
actions: {
asyncAdd({ commit }, payload) {
setTimeout(() => {
this.commit('add', payload)
}, 3000)
}
}
})
//在Vue实例创建时插入Vue实例和Vue组件中
Vue.mixin({
beforeCreate() {
if (this.$options && this.$options.store) {
this.$store = this.$options.store;
} else {
this.$store = this.$parent && this.$parent.$store;
}
},
})
var Child = {
template: '<h1>{{$store.state.num}}</h1>'
}
new Vue({
el: '#app',
components: { Child },
computed: {
num() {
return this.$store.state.num
}
},
store: store,
methods: {
add() {
this.$store.commit('add', 1)
},
asyncAdd() {
this.$store.dispatch('asyncAdd', 10)
}
},
created() {
}
})
</script>
</html>