1.分析Vuex的使用
import Vue from "Vue";
import Vuex from "Vuex";
Vue.use(Vuex);
let stroe = new Vuex.Store({
state:{
count:'我是一个',
name:'赵四'
},
getter:{
xinm(store){
return store.name +'王五'
}
},
mutations:{
add(stroe,options){
stroe.count = options;
},
},
actions:{
pm(store,options){
store.commit('add',options);
}
}
})
export default stroe;
在main.js中
import Vue from "vue";
import stroe from "./store/index.js";
new Vue({
store:store,
render:(h)=>h(App)
});
得出这么个结论
1.Vuex中一定会有install方法----->因为Vue.use(Vuex)就会执行Vuex.install这个方法
2.Vuex中会有一个类Store的这个类
因为他有new Vuex.Store()
myVuex.js中
let Vue;
function install(_Vue){
Vue = _Vue;//保存Vue;
Vue.mixin({
beforeCreate(){
if (this.$options.store){
//如何有this.$options.store这个属性,那么就是根组件
this.$store = this.$options.store
}else if (this.$parent){
//如何有this.$parent这个属性,那么就是他是哪一个的子组件,所以
this.$store = this.$parent.$store;
}
}//在这个全局混入的生命周期函数中,的执行顺序是根组件->父组件->子组件的这样的顺序的
});
//这里为什么要用Vue的全局混入那,因为在new Vue({store})之后,所有的其他Vue实例中都会有这个store属性,所以这里用到了全局的混入;
}
1.所以上面解决的是,在根组件中添加store之后,所有的子组件,都拥有了$store这个属性了
2.原因Vue.use(Vuex);//会执行Vuex的install,我们在install方法中完成上的需求
3.我们利用Vue的全局混入的方式来为其他的组件添加这个属性
myVux.js中的Store类的实现
class Store{
constructor(obj){
//1.obj是一个对象,是new Vuex.Store({})传入的那个对象
//2.obj的结构为
// state:{
// name:'黍离麦秀',
// blue:'蓝色'
// },
// mutations:{
// add(store,options){
// store.state.name = options
// // alert('修改了2')
// // console.log(store,'store.state',options);
// // alert(store.state)
// }
// },
// getters:{
// ppp(state){
// return state.name + '项目项目吗'
// }
// },
// actions:{
// mox(contenx,options){
// console.log(contenx,'contenx')
// contenx.commit('add',options)
// }
2.点state中的数据是响应式的,所以这里我们借助Vue中的响应式来解决这个问题
let vm = new Vue({
data:obj.state
})
this.state = vm.$data//这样就解决了stat中的数据为响应式的问题了;
3.实现mutations
let mutations = obj.mutations;
this.mutations = {
}
Object.keys(mutations).forEach(key=>{
this.mutations[key] = (options)=>{
mutations[key].call(this,this.state,options)
}
1.这里的循环遍历的操作的目的就是,根据参数在this.mutations中添加响应的方法,实现的
2.实现的原理就是,为this.mutations添加对应的属性,属性值为函数,执行这个函数,就是执行mutations中的方法,
3.但是我们要保证mutations中的每一个方法中的this,都是这类的实例
4.mutations中的第一个参数也要是这个类的实例,
5.第三个参数就是传递的值;
6.所以我们里面的函数调用就是mutations[key].call(this,this,options);
});
//现在我们需要实现actions
this.actions = {
};
let actions = obj.actions;
Object.keys(actions).forEach(key=>{
this.actions[key] = (options)=>{
actions[key].call(this,this,options);
}
});
//这里的原理和mutations是差不多的
//实现getter
let getter = obj.getters;
this.getter = {
};
let then = this;
Object.keys(getter).forEach(key=>{
Object.defineProperty(this.getter,key,{
get(){
return getter[key](then);
}
})
})
};
//现在我们需要实现commit方法
commit(type,options){
this.mutations[type](options);
}
//实现dispatch
dispatch(type,options){
this.actions[type](options);
}
}
export default {
install,
Store
}
下面我们就要实现Vuex中的辅助函数
export function mapState(arr=[]){
let obj = {
}
arr.forEach(key=>{
obj[key] = function (){
return this.$store.state[key]
}
})
return obj;
}
1.我们在使用mapState时,是这样使用的
computed:{
...mapState(['name'])
}
2.所以他一定要能使用展开运算符 ...
3.computed是Vue中的计算属性,一般是每一个属性的属性值,是一个方法
所以obj[key] = function (){
}
export function mapMutations(arr = []){
let obj = {
}
arr.forEach(key=>{
obj[key] = function (options){
this.$store.commit(key,options);
}
})
return obj
}
export function mapActions(arr = []){
let obj = {
};
arr.forEach(key=>{
obj[key] = function (options){
this.$store.dispatch(key,options)
}
})
return obj;
}