vuex是一个专门为vue.js设计的集中式状态管理架构。状态?把它理解为在data中的属性需要共享给其他vue组件使用的部分。简单的说就是data需要共用的属性
一、小demo
已经用Vue脚手架工具构建好项目1、引入vuex
1.安装vuex
npm n install vuex --save
注意:一定要加上--save,因为这个包我们在生产环境中要使用
2.新建store文件夹(不是必须),并在文件夹下新建store.js,文件中引入我们的vue和vuex
import Vue from 'vue';import Vuex from 'vuex'
3.使用我们vuex,引入之后用Vue.use进行引用
Vue.use(Vuex)
2、demo
我们这个小demo先声明一个state的count状态,在页面中使用显示这个count,然后可以利用按钮进行加减1.在store.js文件里增加一个常量对象。
const state = {count:3}
2.用export default封装代码,让外部可以引用
export default new Vuex.Store({state})
3.在src/components下新建count.vue
在模板中我们引入我们刚建的store.js文件,并在模板中用{{$store.state.count}}输出count 的值。
<template><div><h2>{{msg}}</h2><h4>{{$store.state.count}}</h4><hr></div></template><script>import store from '@/store/store.js'export default {data(){return {msg: 'Hello Vuex!'}},store}</script>
4.在store.js文件中加入两个改变state的方法
src/store/store.js
const mutations = {add(state){state.count++;},reduce(state){state.count--;}}
这里的mutations是固定的写法,意思是改变的,我们要改变state的数值的方法,必须写在mutations里就可以了。
5.在count.vue模板中加入两个按钮,并调用mutations中的方法
<div><button @click="$mit('add')">+</button><button @click="$mit('reduce')">-</button></div>
这样进行预览就可以实现对vuex中的count进行加减了。
二、state访问状态对象
const state,这个就是我们说的访问状态对象,它是我们SPA(单页应用程序)中的共享值。count.vue页面中,这种写法看着就麻烦
<h4>{{$store.state.count}}</h4><hr>
简便写法
<h4>{{count}}</h4>
这样就好多了可是怎么实现呢???
想要实现有三种方法
1.通过computed的计算属性直接赋值
computed属性可以在输出前,对data中的值进行改变,利用这种特性把store.js中的state值赋值给我们模板中的data值
computed:{count(){return this.$store.state.count;}}
2.通过mapState的对象来赋值
1.用import引入mapState
import { mapState } from 'vuex;
2.在computed计算属性写
computed:mapState{count:state=>state.count}
使用ES6的箭头函数来给count赋值
3.通过mapState的数组来赋值
computed:mapState(['count'])
最简单的写法,在实际项目开发中经常这样使用
三、Mutations修改状态
1、$mit()
Vuex提供了commit方法来修改状态
<button @click="$mit('add')">+</button><button @click="$mit('reduce')">-</button>
store/store.js
const mutations={add(state){state.count++;},reduce(state){state.count--;}}
2、传值
add方法加上一个参数n
const mutations={add(state,n){state.count+=n;},reduce(state){state.count--;}}
在Count.vue里修改按钮的commit( )方法传递的参数,我们传递10,意思就是每次加10
<div><button @click="$mit('add',10)">+</button><button @click="$mit('reduce')">-</button></div>
3、模板获取Mutations方法
$mit()这样的方法写起来麻烦例如:@click=”reduce” 就和没引用vuex插件一样。要达到这种写法,只需要简单的两部就可以了:
1.在模板count.vue里用import引入我们的mapMutations
import { mapState,mapMutations } from 'vuex';
2.在模板的script
标签里添加methods属性,并加入mapMutations
methods:mapMutations(['add','reduce'])
通过上边两部,我们已经可以在模板中直接使用我们的reduce或者add方法
<div><button @click="add(5)">+</button><button @click="reduce">-</button></div>
四、getters计算过滤操作
getters从表面是获取的意思,可以把他看作在获取数据之前进行的一种在编辑,相当于对数据的一个过滤和加工。你可以把它看作store.js的计算属性1、getters基本用法
比如我们现在要对store.js文件中的count进行一个计算属性的操作,就是在它输出前,给它加上10
我们首先要在store.js里用const声明我们的getters属性。
const getters = {count(state) {return state.count+=10;}}
写好了gettters之后,我们还需要在Vuex.Store()里引入
export default new Vuex.Store({state,mutations,getters})
count.vue
computed:{...mapState(["count"]),count(){return this.$store.getters.count;}}
2 用mapGetters简化模板写法
首先用import引入我们的mapGetters
import { mapState,mapMutations,mapGetters } from 'vuex'
在computed属性中加入mapGetters
computed:{...mapState(['count']),...mapGetters(['count'])}
五、actions异步修改状态
actions和之前讲的Mutations功能基本一样,不同点是,actions是异步的改变state状态,而Mutations是同步改变状态。1、在store.js中声明actions
actions是可以调用Mutations里的方法,在actions里调用add和reduce两个方法
const actions = {addAction(context){mit('add',10)},reduceAction({commit}){commit('reduce')}}
在actions里写了两个方法addAction和reduceAction,两个方法传递的参数不一样
context:上下文对象,这里你可以理解称store本身。
{commit}:直接把commit对象传递过来,可以让方法体逻辑和代码更清晰明了
2、模板中的使用
<div><button @click="addAction">addAction+</button><button @click="reduceAction">reduceAction-</button></div>
import引入mapActions
import { mapState,mapMutations,mapGetters,mapActions } from 'vuex'
methods方法
methods:{...mapMutations(['add','reduce']),...mapActions(['addAction','reduceAction'])}
3、增加异步体验
我们现在看的效果和我们用Mutations作的一模一样,肯定有的小伙伴会好奇,那actions有什么用,我们为了演示actions的异步功能,我们增加一个计时器(setTimeOut)延迟执行。在addAction里使用setTimeOut进行延迟执行。
const actions = {addAction(context){mit('add',10)setTimeout(()=>{mit('reduce')},3000)console.log('我比reduce提前执行')},reduceAction({commit}){commit('reduce')}}
count.vue
<template><div><h2>{{msg}}</h2><h4>{{count}}</h4><hr><div><button @click="add(10)">+</button><button @click="reduce">-</button></div><hr><div><button @click="addAction">addAction+</button><button @click="reduceAction">reduceAction-</button></div></div></template><script>import store from '@/store/store.js'import { mapState,mapMutations,mapGetters,mapActions } from 'vuex'export default {data(){return {msg: 'Hello Vuex!'}},// computed:{//方法1//count(){// return this.$store.state.count;//}// },// computed:mapState({//方法2//count:state => state.count// })computed:{...mapState(['count']),//方法3//count(){// return this.$store.getters.count;//}// ...mapGetters(['count']) //简写},methods:{...mapMutations(['add','reduce']),...mapActions(['addAction','reduceAction'])},store}</script>
store.js
import Vue from 'vue';import Vuex from 'vuex'Vue.use(Vuex);const state = {count:3}const mutations = {add(state,n){state.count+=n;},reduce(state){state.count--;}}const getters = {count(state) {return state.count+=10;}}const actions = {addAction(context){mit('add',10)setTimeout(()=>{mit('reduce')},3000)console.log('我比reduce提前执行')},reduceAction({commit}){commit('reduce')}}export default new Vuex.Store({state,mutations,getters,actions})
六、module模块组
随着项目的复杂性增加,我们共享的状态越来越多,这时候我们就需要把我们状态的各种操作进行一个分组,分组后再进行按组编写。module:状态管理器的模块组操作项目不是很大,一般不用1、声明模块组
store.js
const moduleA={state,mutations,getters,actions}
修改原来 Vuex.Stroe里的值:
export default new Vuex.Store({modules:{a:moduleA}})
2、在模板中使用
<h3>{{$store.state.a.count}}</h3>
简写
<h3>{{count}}</h3>
``
computed:{count(){return this.$store.state.a.count;}},