1、原生Vuex
- 引入Vuex
import Vuex from 'vuex'
Vue.use(Vuex)
- 使用
// store/index.js
export default new Vuex.Store({
state: {
// 版本
version: 'v1'
},
getters: {
version: state => state.version
},
actions: {
setVersion({ commit, state }, params) {
return new Promise((resolve, reject) => {
commit('SET_VERSION', params)
resolve()
})
}
},
mutations: {
SET_VERSION(state, params) {
state.version = params
}
}
})
// main.js
import store from './store'
new Vue({
store,
render: h => h(App)
}).$mount('#app')
// xxx.vue
<template>
<div class="home">
{{ this.$store.getters.version }}
</div>
</template>
<script>
mounted() {
setTimeout(() => {
this.change();
}, 1000);
},
methods: {
change() {
this.$store.dispatch("setVersion", "v2");
},
},
</script>
2、手写Vuex
- 从原生Vuex引入来看,
Vue.use(Vuex)
使用use挂载到Vue的实例上,use方法调用vuex的install方法,先来实现install函数
// Vuex.js
const install = (_Vue) => {
Vue = _Vue
Vue.mixin({
beforeCreate() {
// 每个组件添加store:this.$store调用Store实例
// 在所有组件中用this.$store都可以获取到Vuex的Store实例
const options = this.$options
if (options && options.store) {
Vue.prototype.$store = typeof options.store === 'function'
? options.store()
: options.store;
} else if (options.parent && options.parent.$store) {
Vue.prototype.$store = options.parent.$store;
}
}
})
}
- Store类
在原生Vuex中使用new Vuex.Store
创建Store对象实例,所以在自定义Vuex文件中增加Store
类,并通过实现构造函数来进行属性处理
// Vuex.js
class Store {
// 构造函数传参
constructor(options) {
// 将state属性进行响应式处理
this._vm = new Vue({
data: {
state: options.state
}
})
// getters
const getters = options.getters || {}
this.getters = {}
// 遍历getters的key,把对应的key注册到this.getters对象中,返回key对应的getters中方法的执行结果,并传入state
Object.keys(getters).forEach(getterName => {
Object.defineProperty(this.getters, getterName, {
get: () => {
return getters[getterName](this.state)
},
enumerable: true
})
})
// 同步
const mutations = options.mutations || {};
this._mutations = {};
// 遍历mutations,实现内部_mutations方法集
Object.keys(mutations).forEach(mutationName => {
this._mutations[mutationName] = payload => {
mutations[mutationName](this.state, payload)
}
})
// 异步
const actions = options.actions || {};
this._actions = {};
// 遍历actions,实现内部_actions方法集
Object.keys(actions).forEach(mutationName => {
this._actions[mutationName] = payload => {
// 第一个参数是context,里面包含我们需要的state,commit等
actions[mutationName](this, payload)
}
})
}
// 提供外部使用
get state() {
return this._vm.state
}
// 使用箭头函数避免this指向问题
// 在commit方法中获取_mutations
// 接收两个参数,第一个参数是name,方法名称,第二个参数是payload,调用方法的参数
commit = (name, payload) => {
console.log(this)
this._mutations[name](payload)
}
// 使用箭头函数避免this指向问题
// 在dispatch方法中获取_actions
// 接收两个参数,第一个参数是name,方法名称,第二个参数是payload,调用方法的参数
dispatch = (name, payload) => {
console.log(this)
this._actions[name](payload)
}
}
- 使用
将原生Vuex引入方式改成自定义Vuex路径即可实现效果
import Vuex from './Vuex';
Vue.use(Vuex)
如有疑问或不足之处,欢迎交流指正