Vuex实现
- 新创建一个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>