Vuex起步

一. 安装

1.npm安装
cmd指令:npm install vuex --save

2.其他方法
Vuex安装

二. 使用

1、在一个单独的文件store.js里面,导入Vuex,然后注册可供使用的Vuex插件,而后创建一个新的状态存储库store并传入一个对象来配置这个存储库,这里的state相当于Vue实例里面的data,保存初始的属性值

import Vue from 'vue'
import Vuex from 'vuex'

//注册vuex插件
Vue.use(Vuex);

//创建一个新的状态存储库
//store是一个方法,我们要传入一个对象来配置这个存储库
export const store = Vuex.Store({
    //state属性是一个对象,可以用来保存应用中需要的全部状态
    state: {
        counter: 0
    }
});

2、获取state中的数据,例如counter,可以直接使用this.$store.state.counter调用,若是在其他页面,则需要在根示例的文件中导入存储库store,并在根实例内注册它就可以通过前面的语句访问存储库了,而且由于在根实例内导入注册了,故不需要在其他子组件中再导入存储库,就可以直接访问调用

import Vue from 'vue'
import App from './App.vue'
//导入存储库
import { store } from './store/store.js'
 
//在根Vue实例内注册vuex,然后才能在整个应用内使用
new Vue({
  el: '#app',
  store: store,
  render: h => h(App)
})

3、对于getter的使用,就像计算属性一样,getter的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。对于getters的理解主要作用是对state属性进行计算,可以理解类似于Vue中computed,getters里面装的是计算方法。

import Vue from 'vue'
import Vuex from 'vuex'

//注册vuex插件
Vue.use(Vuex);

//创建一个新的状态存储库
//store是一个方法,我们要传入一个对象来配置这个存储库
export const store = Vuex.Store({
    //state属性是一个对象,可以用来保存应用中需要的全部状态
    state: {
        counter: 0
    },
    //使用getters会使得应用更加高效
    getters: {
        //doubleCounter实际上是一个函数,这个函数有一个参数state,当该函数别调用的时候,vue会自动传入state
        doubleCounter: state => {
            return state.counter * 2;
        },
        stringCounter: state => {
            return state.counter + ' Clicks';
        }
    }
});

调用方法分两种:一种是直接this.$store.getters.(getter方法名称)调用;另外一种是引用store来调用,在需要引用的组件里面导入使用,当然调用为store.getters.(getter方法名称)

<script>
    export default {
        computed: {
            counter() {
                return this.$store.getters.doubleCounter;
            },
            clicks() {
                return this.$store.getters.stringCounter;
            }
        }
    }
</script>

注意:当调用的getter变多时,代码会变得冗余,这个时候Vuex提供了一个辅助函数mapGetters,它能自动创建所有计算属性方法,供我们进行计算属性的重写,而且这属于对象展开运算符的内容,在npm中可以添加一个包使用,npm install --save-dev babel-preset-stage-2(为…语法提供支持),并且在添加完这个包后,还需要进入.babelrc的文件,在presets数组中添加一个新项目即为[“stage-2”]

<script>
    //mapGetters自动创建所有计算属性方法
    import { mapGetters } from 'vuex'; 
    export default {
        //mapGetters的参数是一个数组
        computed: {
        	...mapGetters([
            	//会在后台自动生成计算属性,然后会被映射到getter   
            	'doubleCounter',
            	//当然也可以对计算属性的名称进行重写,使用对象形式
	            sc: 'stringCounter'
        	])
        }
    }
</script>

在这里插入图片描述

4、Vuex的五大核心概念之一的mutation:更改Vuex的store中的状态的唯一方法是提交mutation。是存放处理数据的方法的集合。

其使用方法是,先在创建的store存储库中添加mutations属性,然后往里面添加需要的方法,方法参数为store中的state,因为mutation就是主要就是为了修改state状态。

import Vue from 'vue'
import Vuex from 'vuex'

//注册vuex插件
Vue.use(Vuex);

//创建一个新的状态存储库
//store是一个方法,我们要传入一个对象来配置这个存储库
export const store = new Vuex.Store({
    //state属性是一个对象,可以用来保存应用中需要的全部状态
    state: {
        counter: 0
    },
    //使用getters会使得应用更加高效
    getters: {
        //doubleCounter实际上是一个函数,这个函数有一个参数state,当该函数别调用的时候,vue会自动传入state
        doubleCounter: state => {
            return state.counter * 2;
        },
        stringCounter: state => {
            return state.counter + ' Clicks';
        }
    },
    //mutation也是保留属性,就是一个列表,或者说是一些可执行的方法
    //mutation的优点在于同步跟踪存储库中属性的变化,但是不能异步执行
    mutations: {
        //传入state作为参数输入
        increment: state => {
            state.counter ++;
        },
        decrement: state => {
            state.counter --;
        }
    }
});

若想要在其它组件中调用这些个修改state状态的方法,使用语法this.$store.commit(‘方法名称’)来触发修改方法

<script>
    export default {
        methods: {
            increment() {
				this.$store.commit('increment');
			},
			decrement() {
				this.$store.commit('decrement');
			}
        }
    }
</script>

当然,为了代码简洁也有和mapGetters类似的辅助函数,比如mapMutations,用法和mapGetters几乎一模一样(而且也有mapState,本文不做描述,详情参考:mapState

<script>
    import { mapMutations } from 'vuex';
    export default {
        methods: {
            ...mapMutations([
                'increment',
                'decrement'
            ])
        }
    }
</script>

5、actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据(但是还是通过mutation来操作,因为只有它能操作)。Action 类似于 mutation,不同在于:

Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。

使用方法:先在创建的store存储库中添加actions属性,然后添加一个函数方法,这个方法函数的参数为context,因为能提交mutation的对象方法commit是在action属性的context对象中。语法为:context.commit('需要调用的mutation中的方法名');

例如:

actions: {
        //context由vuex自动传入,有了context就能访问到commit方法
        //context里面有很多方法
        increment: context => {
             context.commit('increment');
        }
}

另一种写法(使用参数解构来简化代码):

actions: {
        //就可以直接使用对象方法了
        increment: ({ context }) => {
             commit('increment');
        }
}

进行异步操作:

actions: {
        //就可以直接使用对象方法了
        increment: ({ context }) => {
             commit('increment');
        },
        asyncIncrement: ({ commit }) => {
            setTimeout(() => {
                commit('increment');
            }, 1000);
        }
}

当然,为了代码简洁也有和mapMutations类似的辅助函数,比如mapActions,用法和mapMutations几乎一模一样。

<script>
    import { mapActions } from 'vuex';
    export default {
        methods: {
            ...mapActions([
                'increment',
                'decrement'
            ])
        }
    }
</script>

为了能够调用通过mapActions映射创建的方法,我们使用语句this.$store.dispatch('mapActions中需要调用的方法名')

<script>
    import { mapActions } from 'vuex';
    export default {
        methods: {
            ...mapActions([
                'increment',
                'decrement'
            ]),
            increment() {
            	this.$store.dispatch('increment');
        }
    }
</script>

我们也可以在每个action中传入一个参数,action把传入的参数传递给mutation,因为mutation不仅可以访问state,其第二个参数就可以是action传递过来的参数。

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

export const store = new Vuex.Store({
    state: {
        counter: 0
    },
    getters: {
        doubleCounter: state => {
            return state.counter * 2;
        },
        stringCounter: state => {
            return state.counter + ' Clicks';
        }
    },
    mutations: {
        increment: (state, payload) => {
            state.counter += payload;
        },
        decrement: (state, payload) => {
            state.counter -= payload;
        }
    },
    actions: {
    	//payload作为传入的参数传递给触发的mutation方法
        increment: ({ commit }, payload) => {
            commit('increment', payload);
        },
        decrement: ({ commit }, payload) => {
            commit('decrement', payload);
        },
        asyncIncrement: ({ commit }, payload) => {
            setTimeout(() => {
                commit('increment');
            }, 1000);
        },
        asyncDecrement: ({ commit }, payload) => {
            setTimeout(() => {
                commit('decrement');
            }, 1000);
        } 
    }
});
<template>
    <div>
        <button class="btn btn-primary" @click="increment(100)">Increment</button>
        <button class="btn btn-primary" @click="decrement(50)">Decrement</button>
    </div>
</template>

<script>
    import { mapActions } from 'vuex';
    export default {
        methods: {
            ...mapActions([
                'increment',
                'decrement'
            ])
        }
    }
</script>

我们也可以把对象当做一个参数传入,这样做的好处是一个对象可以有多个属性,不会被写死。
例如:asyncIncrement里面设置了两个属性,分别为by(用来设置步长)和duration(设置间隔时间)。

<template>
    <div>
        <button class="btn btn-primary" @click="asyncIncrement({by: 50, duration: 500})">Increment</button>
        <button class="btn btn-primary" @click="asyncDecrement({by: 50, duration: 500})">Decrement</button>
    </div>
</template>

然后在回调函数中就直接调用。

    actions: {
    	//payload作为传入的参数传递给触发的mutation方法
        increment: ({ commit }, payload) => {
            commit('increment', payload);
        },
        decrement: ({ commit }, payload) => {
            commit('decrement', payload);
        },
        asyncIncrement: ({ commit }, payload) => {
            setTimeout(() => {
                commit('increment', payload.by);
            }, payload.duration);
        },
        asyncDecrement: ({ commit }, payload) => {
            setTimeout(() => {
                commit('decrement', payload.by);
            }, payload.duration);
        } 
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值