Vuex介绍
Vuex是一个专为Vue,js应用程序开发的集中式状态管理架构。它把我们项目中所用到的组件对其状态进行集中式的存储于管理,并以相应的规则保证状态得以按照我们想要的效果发生变化。
简单的来说,Vuex就是vue为了方便数据的操作而建立的一个“前端数据库”。我们都知道Vue中组件间本身是不共享作用域的,B组件想要拿到A组件中的数据,需要用到emit等特殊的语句去实现通信。随着项目的变大,组件之间的通信也就越来越难以维护。这时,如果有一个全局变量store,用来存共享的数据state,然后把A组件想要共享的数据挂到B组件上。这样B组件通过state就可以拿到这个数据了。这样一来,由store去统一管理数据,则数据的传递就更加清晰明了,易于维护。当然,B组件确实拿到了A组件中的数据,但是这个数据不是一成不变的。A要操作这个数据,我们就需要在这个数据改变的时候通知一下B,B也跟着变就好了。Vuex其实就是帮我们来做这件事的,帮我们集中存储管理数据。
Vuex核心
通过上面的了解,想必大家也能感觉到Vuex最重要的就是存储应用中大部分状态state的库,这个库就是store。
Vuex和单纯的全局对象的区别
1.Vuex的状态存储是响应式的,当Vue组件从store中读取状态的时候,若store中的状态发生变化,那么相应的组件也会随之改变;
2.store中的状态是不能直接改变的,改变它的唯一方法就是显示地提交(commit) mutation。
说了这么多,大家已经等不及想要去实践一下了吧,下面让我们写一个小demo,感受一下Vuex的作用。
Vuex使用
1.用Vue-cli自行搭建Vue项目;
2.引入Vuex
脚本安装:npm install vuex –save-dev
在src目录下新建vuex文件夹,里面创建store,js,引入vue和vuex,并进行使用
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
3.在main.js中进行引用
import store from './vuex/store'
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
4.在store.js中创建变量,创建执行的方法
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const state = {//共享值
count:1
}
const mutations = {
increment:state => state.count++,
decrement:state => state.count--
}
export default new Vuex.Store({//一个容器,包含应用中的大部分状态
state,//数据库
mutations//中间量,把数据存入数据库的API,用来操作数据修改state
});
5.在你创建的vue中引入vuex获取操作数据
<template>
<div>
<h2>{{msg}}</h2>
<p>{{$store.state.count}}</p>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
</template>
<script>
import store from '@/vuex/store';
import {mapState,mapMutations} from 'vuex';
export default {
data(){
return{
msg:'大家好'
}
},
store,
methods:mapMutations([//模板获取Vuex里面mutations中的方法,以代替$store.commit()的繁琐写法
'increment','decrement'
])
}
</script>
<style>
</style>
完成上述的步骤就可以实现组件从vuex中拿数据,以及操作数据了。由此可知,对于一个store容器来说,state和mutation是必不可少的。当然vuex还为我们提供了更加方便的拿取数据和操作数据的方法getters和actions。
6.getters取值
getters是一个纯函数,接收参数state,可以对state进行相关处理,然后返回我们想要取的值。如下:
在store.js里面添加getters
const getters = {
add:state => state.count += 10
}
export default new Vuex.Store({
state,//数据库
mutations,//必须在store里面,它是个中间量,修改数据方法的集合,把数据存入数据库的API,用来修改state
getters//从数据库里取数据的API,是一个“纯函数”,就是不会对原数据造成影响的函数
});
在vue文件中引入mapGetters获取add方法
import {mapState,mapMutations,mapGetters} from 'vuex';
computed:{
...mapGetters([
'add'
])
}
将获取到的值添加到template模板中
<p>{{add}}</p>
这时,你会发现p中的值在每次变化的时候,会先加10,这就是getters先对获取的值进行了处理然后再返回。
你会发现mapGetters写在了computed里面,虽然getter我们写的是函数,但是我们应该把它当成计算属性来用。
7.action操作数据
在store.js里面添加update的actions用于更新数据,与此同时需要在mutations中增加upDate用于存储更新的数据。
const mutations = {
increment:state => state.count++,
decrement:state => state.count--,
upDate:state => state.count = 2
}
const actions = {
update:({commit}) => commit('upDate')
}
当然,还是需要把actions放入到store中
export default new Vuex.Store({
state,//数据库
getters,//从数据库里取数据的API,是一个“纯函数”,就是不会对原数据造成影响的函数
actions,//对数据进行处理,处理完再存储到数据库中
mutations//必须在store里面,它是个中间量,修改数据方法的集合,把数据存入数据库的API,用来修改state
});
在vue文件中引入mapActions获取update方法
import {mapState,mapMutations,mapGetters,mapActions} from 'vuex';
methods:{
...mapMutations([
'increment','decrement','upDate'
]),
...mapActions([
'update'
])
}
template模板中添加更新按钮
<button @click="update">更新</button>
这时,你就会发现,点击更新按钮,值会先改为我们赋的值然后再进行其他操作。当然,看到这儿,你可能会好奇action和mutation起到的作用是一样的,使用action显得多此一举。其实不然,action与mutation的区别在于action是可以异步操作数据,而mutation使用的时候需要commit,但是commit是同步函数,所以mutation只能是同步执行的。
8.异步action
actions通过将mutations里面处里数据的方法变成可异步的处理数据的方法。当然有人又会问,既然mutation不能处理异步而action可以,那么什么不直接用action呢?上文已经解释过,在vue里面,store中的状态是不能直接改变的,改变它的唯一方法就是显示地提交(commit) mutation。
为了模拟异步,下面写了一个setTimeout函数
在store.js里面添加action
const mutations = {
increment:state => state.count++,
decrement:state => state.count--,
upDate:state => state.count = 2,
firstClick:() => console.log('我是第一次点击的'),
secondClick:() => console.log('我是第二次点击的'),
}
const actions = {
update:({commit}) => commit('upDate'),
first:({commit}) => setTimeout(()=> commit('firstClick'),2000),
second:({commit}) => commit('secondClick'),
}
在vue中同上面的引入,在template中加入操作按钮
<button @click="first">action第一次点击</button>
<button @click="second">action第二次点击</button>
这样,你先后点击两个按钮,控制台里就会先展示action第二次点击,说明action可以实现异步操作。
写到这儿,vuex就介绍的差不多了,下面让我们来总结一下。
在vuex中,state相当于数据库,action处理数据,然后通过mutation把处理后的数据放入数据库(state)中,谁要用就通过getter从数据库(state)中取。(action ==> mutation ==> state ==> getter)