Vuex主要作用是一个数据仓库,管理的是状态。可以存储数据,使得该项目下所有的页面可以访问该仓库中的数据或方法
这里前提需要搭建一个vue项目,并且有一个组件Count.vue,通过vue-router可以跳转到该组件,具体实现这里不再赘述
一、安装Vuex,初体验
npm i vuex -S在 src 目录下新建一个文件夹 vuex , 在该目录下新建一个 store.js , 然后写入如下代码
import Vue from 'vue' //引入vue
import Vuex from 'vuex' //引入vuex
Vue.use(Vuex) //在vue中使用vuex现在有个需求是,需要在页面上显示一个count, 并且这个count是从vuex中读取出来的,并且在页面中可以通过两个按钮分别改变vuex中count的 加减
首先,在 store.js 下写入如下代码:
//定义数据
const state = {
count: 1
}
export default new Vuex.Store({
state
})Count.vue 文件中有如下代码:
<template>
<div>
<h2>{{$store.state.count}}</h2>
</div>
</template>
<script>
import store from '@/vuex/store';
export default {
data(){
return{
}
},
store
}
</script>接下来我们需要通过两个按钮来改变 count 的值修改 Count.vue 为如下:
<template>
<div>
<h2>{{$store.state.count}}</h2>
<p>
<button>+</button>
<button>-</button>
</p>
</div>
</template>
<script>
import store from '@/vuex/store';
export default {
data(){
return{
}
},
store
}
</script>接下来我们需要在 vuex 中定义方法,在 store.js 文件添加如下内容:
//定义方法
const mutation = {
add(state){
state.count++;
},
reduce(state){
state.count--;
}
}
//将mutations添加到vuex
export default new Vuex.Store({
state,
mutations
})注意:要想改变 Vuex 中 state 的值,只能通过 mutations 改变
然后在 Count.vue 中调用 vuex 中定义的方法来修改 state 中 count 的值
//通过commit方法触发vuex的mutations的方法
...
<p>
<button @click="$store.commit('add')">+</button>
<button @click="$store.commit('reduce')">-</button>
</p>
...二、State访问状态对象
state指的是状态对象,在SPA(单页应用)中,状态对象用来保存所有组件公用的状态,比如用户登录信息
需求是用不同方法在组件中输出state内的数据
首先打开 Count.vue
2.1 第一种输出方式
<h2>{{$store.state.count}}</h2>在第一节中就是用的是这种输出方式,在标签内写的太麻烦,请看第二种方式
2.2 第二种输出方式,计算属性(computed)
<template>
<div>
<h2>{{count}}</h2>
</div>
</template>
<script>
import store from '@/vuex/store'
export default {
computed:{
count(){
return this.$store.state.count
}
},
store
}
</script>2.3 第三种输出方式,mapState
<template>
<div>
<h2>{{count}}</h2>
</div>
</template>
<script>
import store from '@/vuex/store'
import {mapState} from 'vuex'
export default {
computed:mapState({
count:state => state.count
}),
store
}
</script>2.4 第四种输出方式,mapState(数组形式)
<template>
<div>
<h2>{{count}}</h2>
</div>
</template>
<script>
import store from '@/vuex/store'
import {mapState} from 'vuex'
export default {
computed:mapState(['count']),//数组中是字符串,该组件需要state里面的哪些数据,就将这些数据传在mapState数组中
store
}
</script>三、Mutations修改状态
Mutations中定义的方法是用来修改vuex中的state的状态的,有两个参数,第一个参数是state对象,第二个参数是pload,pload接收的是调用mutations种方法传的参数
这里有个需求是需要点击增加按钮之后自定义增加的数量,最开始的时候是加1
首先,先来改写一下 Mutations 中 add 方法
const mutation = {
add(state,pload){
state.count+=pload;
},
reduce(state,pload){
state.count--;
}
}在 Count.vue 文件中调用 Mutations 中定义的方法来修改 State 中的状态
...
<p>
<button @click="$store.commit('add',10)">+</button>
<button @click="$store.commit('reduce')">-</button>
</p>
...这样就可以在 Count.vue 中每次点击 加号 按钮, State 中的 count 就会 加10
在vue文件中用commit方法触发Mutations中定义的方法,第一个参数是Mutations中定义的方法名,第二个参数是要传递给该方法的参数
3.1 引用方法
在 Count.vue 中同样先 引入 store,并且从 vuex 中引入 mapMutations
import store from '@/vuex/store'
import { mapState,mapMutations } from 'vuex'
export default {
data(){
return {
}
},
computed:mapState(['count']),
methods:mapMutations(['add','reduce'])
}然后在 Count.vue 模板中直接调用该 reduce 方法
...
<p>
<button @click="$store.commit('add',10)">+</button>
<button @click="reduce">-</button>
</p>
...四、Getters(Vuex中的计算属性)
相当于vue中的computed,计算属性
首先打开 store/index.js ,先定义 getter 要进行什么处理
const getter = {
count:(state) => state.count += 100
}回到 Count.vue修改 computed 写法
...
computed:{
...mapState(['count']),
count:()=>{
return this.$store.getters.count
}
}
...简写
import { mapGetters } from 'vuex'
...
computed:{
...mapState(['count']),
...mapGetters(['count'])
}
...五、Actions(异步修改状态)
首先打开 store/index.js
// 定义异步方法
const actions = {
addAction(context){
context.commit('add',10)
},
reduceAction({commit,dispatch}){
commit('reduce')
}
}回到 Count.vue 在模板中这样写:
...
<p>
<button @click="addAction">+</button>
<button @click="reduceAction">-</button>
</p>
...同样将 methods 改成如下写法
import { mapActions } from 'vuex'
...
methods:{
...mapMutations(['add','reduce']),
...mapActions(['addAction','reduceAction'])
}
...六、module模块组
模块组的定义就是将state、mutations、actions、getter放在一个js文件中,该js称为一个模块,将多个模块放在一个modules里面形成模块组
6.1 声明模块组
首先打开 store/index.js
// 模块文件里包含了该模块对应的state、mutations、actions、getter
import user from './user'
import goods from './goods'
const moduleA = {
user
}
const moduleB = {
goods
}
export default new Vuex.Store({
modules:{
a:moduleA,
b:moduleB
}
})6.2 组件中使用
...
<p>{{$store.state.a.count}}</p>
...或
<p>{{count}}</p>
<script>
...
computed : {
// a指的store->modules下的模块名
count() => this.$store.state.a.count
}
...
</script>七、在Nuxt.js中使用Vuex
在Nuxt.js中如果使用Vuex,我们不需要安装引用,Nuxt已经帮我们解决了这个问题
只需要在Nuxt的store目录下创建js文件即可
每一个js文件都可以是一个模块(当然index.js除外,这是根模块)
首先创建一个 tools.js 模块
export const state = () => ({})
export const mutations = {}
export const actions = {
getTools({commit,dispatch}){
return axios.get('/tools/searchAll')
}
}在组件中使用,请参考如下代码
//如果要使用state
this.$store.state.count //取跟模块下state中的count
this.$store.state.tools.count //取tools模块下state中的count
//如果要使用mutations
this.$store.commit('SET_TOKEN',params) //根模块下的mutations方法
this.$store.commit('tools/SET_TOKEN',params) //tools模块下的mutations方法
//如果要使用actions
this.$store.dispatch('getTools') //根模块下的actions中的getTools方法
this.$store.dispatch('tools/getTools') //tools模块下的actions中的getTools方法