什么是vuex?
vuex是个状态(也可以说公共值)管理器。简单概括就是,它相当于一个公共仓库,任何组件都可以使用(包括里面的状态值)它。
vuex作用:因为他相当于一个公共仓库,那么我们不管父组件与子组件间还是同胞组件间,他们之间传递信息就方便很多了。
vuex例子
大家可以根据下面的讲解在这进行印证。
首先,下载vuex
npm install vuex –save
其次,创建store.js来放置需要管理的状态以及相应的api
import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex)
export default new vuex.Store({
state:{
show:false
},
getters:{
... //下面讲解api时补充
},
mutations:{
... //下面讲解api时补充
},
actions:{
... //下面讲解api时补充
}
})
然后,在main.js中引入,使其注入根实例
// main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from 'xxx/xxx/store.js'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store, //这里添加store,注入根实例
components: { App },
template: '<App/>'
})
最后,以上的步骤已经引入了vuex插件,现在只要使用就行了
// 某个组件
<template>
<div v-if = "this.$store.state.show">显不显示呢?</div> //显示 0
</template>
vuex中的四个api
状态管理器,顾名思义就是要管理状态的以供方便组件的使用。那么vuex提供的api也就是用于管理状态的。
- state : 相当于组件中的data
- getters : 相当于computed
- mutations : 相当于methods
- actions : 用于mutations的异步
state
他的作用相当于组件中的data的作用。只不过state中的值可以让每个组件调用。
//用法
...
state:{
count:0
// 将我们在其他组件中经常需要用到的状态(值)写在这
}
...
getters
其作用相当于组件中的computed。这里记住一个要点,有助于理解:这里的state中的值常常用于多个组件,一个state中的值改变了,其他组件中使用到state的值也会改变。“动一发引全身”
// 某个组件中
<template>
<div v-if = "show">显不显示呢?</div>
</template>
<script>
export default {
...
computed:{
show(){
return !this.$store.state.show
}
}
...
}
</script>
上面的做法很常规,没毛病。但是这种做法用在一两个组件中还好。如果state中的show值很多组件都要用到呢?如果每个组件都用computed那未免有些繁琐。所以在store中先计算(getters)好再给予组件(s),就简单许多
// store.js
...
getters:{
show(state){
return !state.show
}
}
...
在组件中的引用,
<template>
<div v-if = "this.$store.getters.show">显不显示呢?</div>
</template>
mutations
相当于组件中的methods。其最大的好处在于它可以任意并且简单的调用state中的值。
比如,我们在某个组件中,要判断父组件的某个按钮是否被按下,然后还要确定另一个兄弟组件的按钮是否被按下,然后才能显示该组件。这种情况,如果我们不用vuex的话,是很麻烦的
// store.js
...
state:{
show:false,
fatherShow:false,
brotherShow:false
},
mutations:{
showOrNot的方,法名(state){
if (state.fatherShow&&state.brotherShow){
state.show = !state.show
}
}
}
...
在组件中
<template>
<div v-if = "this.$store.getters.show">显不显示呢?</div>
<button @click="this.$store.commit('showOrNot')">点击我,看显不显示</button>
</template>
这样是不是就方便了很多?另外,我们使用mutations时需要注意两点。
- mutations是同步的,并且异步的操作最好不要在这使用
- mutations 中的方法是不分组件的,如果你在modules1,modules2…等等的mutations中有同样的showOrNot的方法名,虽然方法不同,但是都会调用。“动一发引全身”。所以使用mutations时最好避免方法名相同(在不使用vuex提供的命名空间的前提下)
什么是modules?不用急,后面会提到
mutations中的方法也可以传参(Payload)
具体请看文档,这里就不详细讲解
// 在组件中调用并传参
this.$store.commit('add',10)
或者
this.$store.commit('add',{
amount:10
})
或者
this.$store.commit({
type: 'add',
amount: 10
})
在store.js中
根据上面举的例子,接受参数的方法依次是
add (state, n) {
state.count += n
}
或者
add (state, payload) {
state.count += payload.amount
}
或者
add (state, payload) {
state.count += payload.amount
}
没错,第二和第三种举的例子的接受参数的方法都是一样的,并且它们是以对象的形式传参
actions
其作用是解决了mutations中不能使用异步的问题。并且还提供了可以调用mutations中多个方法的api。
比如,像上面mutations举的例子,如果我们想点击某个组件的按钮,使得父组件不显示,兄弟组件也不显示,但是两者方法不能合并,这时我们可以用actions使两种方法一起调用
// store.js
...
mutations:{
notFathershow(state){
state.fatherShow = false
},
notBrothershow(state){
state.brotherShow = false
}
},
actions:{
allDown(context){ //这里的context和我们使用的$store拥有相同的对象和方法
context.commit('notFathershow');
context.commit('notBrothershow');
//这里也可以使用异步操作
}
}
...
在组件中,
<template>
<div v-if = "this.$store.getters.show">显不显示呢?</div>
<button @click="this.$store.dispatch('allDown')">父组件,兄弟组件都不显示</button>
</template>