那如何獲取到state的數(shù)據(jù)呢蜒秤?
一般會在組件的計算屬性(computed)獲取state的數(shù)據(jù)(因為,計算屬性會監(jiān)控數(shù)據(jù)變化贝咙,一旦發(fā)生改變就會響應(yīng))
<!DOCTYPE html>
<html lang="en">
<head>
? ? <meta charset="UTF-8">
? ? <meta name="viewport" content="width=device-width, initial-scale=1.0">
? ? <meta http-equiv="X-UA-Compatible" content="ie=edge">
? ? <title>Document</title>
</head>
<script src="./js/vuex.js"></script>
<script src="./js/vue2.0.js"></script>
<body>
? ? <div id="app">
? ? ? ? <hello></hello>
? ? </div>
</body>
<script>
? ? Vue.use(Vuex);
? var myStore =? new Vuex.Store({
? ? ? ? state:{
? ? ? ? ? ? //存放組件之間共享的數(shù)據(jù)
? ? ? ? ? ? name:"jjk"
? ? ? ? },
? ? ? ? mutations:{
? ? ? ? ? ? //顯式的更改state里的數(shù)據(jù)
? ? ? ? },
? ? ? ? getters:{
? ? ? ? ? ? //過濾state數(shù)據(jù)
? ? ? ? },
? ? ? ? actions:{
? ? ? ? ? ? //
? ? ? ? }
? ? });
? ? Vue.component('hello',{
? ? ? ? template:"<p>{{name}}</p>",
? ? ? ? computed: {
? ? ? ? ? ? name:function(){
? ? ? ? ? ? ? ? return this.$store.state.name
? ? ? ? ? ? }
? ? ? ? },
? ? ? ? mounted:function(){
? ? ? ? ? ? console.log(this)
? ? ? ? }
? ? })
? ? new Vue({
? ? ? ? el:"#app",
? ? ? ? data:{
? ? ? ? ? ? name:"dk"
? ? ? ? },
? ? ? ? store:myStore,
? ? ? ? mounted:function(){
? ? ? ? ? ? console.log(this)
? ? ? ? }
? ? })
</script>
</html>
state:用來存放組件之間共享的數(shù)據(jù)样悟。他跟組件的data選項類似,只不過data選項是用來存放組件的私有數(shù)據(jù)庭猩。
getters:有時候窟她,我們需要對state的數(shù)據(jù)進行篩選,過濾蔼水。這些操作都是在組件的計算屬性進行的震糖。如果多個組件需要用到篩選后的數(shù)據(jù),那我們就必須到處重復(fù)寫該計算屬性函數(shù)趴腋;或者將其提取到一個公共的工具函數(shù)中试伙,并將公共函數(shù)多處導(dǎo)入 - 兩者都不太理想嘁信。如果把數(shù)據(jù)篩選完在傳到計算屬性里就不用那么麻煩了,getters就是干這個的疏叨,你可以把getters看成是store的計算屬性潘靖。getters下的函數(shù)接收接收state作為第一個參數(shù)。那么蚤蔓,組件是如何獲取經(jīng)過getters過濾的數(shù)據(jù)呢卦溢? 過濾的數(shù)據(jù)會存放到$store.getters對象中。具體看一個例子:
<!DOCTYPE html>
<html lang="en">
<head>
? ? <meta charset="UTF-8">
? ? <meta name="viewport" content="width=device-width, initial-scale=1.0">
? ? <meta http-equiv="X-UA-Compatible" content="ie=edge">
? ? <title>Document</title>
</head>
<script src="./js/vuex.js"></script>
<script src="./js/vue2.0.js"></script>
<body>
? ? <div id="app">
? ? ? ? <hello></hello>
? ? </div>
</body>
<script>
? ? Vue.use(Vuex);
? var myStore =? new Vuex.Store({
? ? ? ? state:{
? ? ? ? ? ? //存放組件之間共享的數(shù)據(jù)
? ? ? ? ? ? name:"jjk",
? ? ? ? ? ? age:18
? ? ? ? },
? ? ? ? mutations:{
? ? ? ? ? ? //顯式的更改state里的數(shù)據(jù)
? ? ? ? },
? ? ? ? getters:{
? ? ? ? ? ? getAge:function(state){
? ? ? ? ? ? ? ? return state.age;
? ? ? ? ? ? }
? ? ? ? },
? ? ? ? actions:{
? ? ? ? ? ? //
? ? ? ? }
? ? });
? ? Vue.component('hello',{
? ? ? ? template:"<p>姓名:{{name}} 年齡:{{age}}</p>",
? ? ? ? computed: {
? ? ? ? ? ? name:function(){
? ? ? ? ? ? ? ? return this.$store.state.name
? ? ? ? ? ? },
? ? ? ? ? ? age:function(){
? ? ? ? ? ? ? ? return this.$store.getters.getAge
? ? ? ? ? ? }
? ? ? ? },
? ? ? ? mounted:function(){
? ? ? ? ? ? console.log(this)
? ? ? ? }
? ? })
? ? new Vue({
? ? ? ? el:"#app",
? ? ? ? data:{
? ? ? ? ? ? name:"dk"
? ? ? ? },
? ? ? ? store:myStore,
? ? ? ? mounted:function(){
? ? ? ? ? ? console.log(this)
? ? ? ? }
? ? })
</script>
</html>
mutations:前面講到的都是如何獲取state的數(shù)據(jù)秀又,那如何把數(shù)據(jù)存儲到state中呢单寂?在 Vuex store 中,實際改變 狀態(tài)(state) 的唯一方式是通過 提交(commit) 一個 mutation吐辙⌒觯 mutations下的函數(shù)接收state作為參數(shù),接收一個叫做payload(載荷)的東東作為第二個參數(shù)昏苏,這個東東是用來記錄開發(fā)者使用該函數(shù)的一些信息尊沸,比如說提交了什么,提交的東西是用來干什么的贤惯,包含多個字段洼专,所以載荷一般是對象(其實這個東西跟git的commit很類似)還有一點需要注意:mutations方法必須是同步方法!
具體看實例:
<!DOCTYPE html>
<html lang="en">
<head>
? ? <meta charset="UTF-8">
? ? <meta name="viewport" content="width=device-width, initial-scale=1.0">
? ? <meta http-equiv="X-UA-Compatible" content="ie=edge">
? ? <title>Document</title>
</head>
<script src="./js/vuex.js"></script>
<script src="./js/vue2.0.js"></script>
<body>
? ? <div id="app">
? ? ? ? <hello></hello>
? ? </div>
</body>
<script>
? ? Vue.use(Vuex);
? var myStore =? new Vuex.Store({
? ? ? ? state:{
? ? ? ? ? ? //存放組件之間共享的數(shù)據(jù)
? ? ? ? ? ? name:"jjk",
? ? ? ? ? ? age:18,
? ? ? ? ? ? num:1
? ? ? ? },
? ? ? ? mutations:{
? ? ? ? ? ? //顯式的更改state里的數(shù)據(jù)
? ? ? ? ? ? change:function(state,a){
? ? ? ? ? ? ? ? //? state.num++;
? ? ? ? ? ? ? console.log(state.num += a);
? ? ? ? ? ? }
? ? ? ? },
? ? ? ? getters:{
? ? ? ? ? ? getAge:function(state){
? ? ? ? ? ? ? ? return state.age;
? ? ? ? ? ? }
? ? ? ? },
? ? ? ? actions:{
? ? ? ? ? ? //
? ? ? ? }
? ? });
? ? Vue.component('hello',{
? ? ? ? template:"<p @click='changeNum'>姓名:{{name}} 年齡:{{age}} 次數(shù):{{num}}</p>",
? ? ? ? computed: {
? ? ? ? ? ? name:function(){
? ? ? ? ? ? ? ? return this.$store.state.name
? ? ? ? ? ? },
? ? ? ? ? ? age:function(){
? ? ? ? ? ? ? ? return this.$store.getters.getAge
? ? ? ? ? ? },
? ? ? ? ? ? num:function(){
? ? ? ? ? ? ? ? return this.$store.state.num
? ? ? ? ? ? }
? ? ? ? },
? ? ? ? mounted:function(){
? ? ? ? ? ? console.log(this)
? ? ? ? },
? ? ? ? methods: {
? ? ? ? ? ? changeNum: function(){
? ? ? ? ? ? ? ? //在組件里提交
? ? ? ? ? ? ? ? // this.num++;
? ? ? ? ? ? ? ? this.$store.commit('change',10)
? ? ? ? ? ? }
? ? ? ? },
? ? ? ? data:function(){
? ? ? ? ? ? return {
? ? ? ? ? ? ? ? // num:5
? ? ? ? ? ? }
? ? ? ? }
? ? })
? ? new Vue({
? ? ? ? el:"#app",
? ? ? ? data:{
? ? ? ? ? ? name:"dk"
? ? ? ? },
? ? ? ? store:myStore,
? ? ? ? mounted:function(){
? ? ? ? ? ? console.log(this)
? ? ? ? }
? ? })
</script>
</html>
可以看出:更改state的數(shù)據(jù)并顯示在組件中孵构,有幾個步驟:1. 在mutations選項里屁商,注冊函數(shù) 函數(shù)里面裝邏輯代碼。2.在組件里颈墅,this.$store.commit('change',payload) ?注意:提交的函數(shù)名要一一對應(yīng) ?3.觸發(fā)函數(shù)蜡镶,state就會相應(yīng)更改 4.在組件的計算屬性里?this.$store.state 獲取你想要得到的數(shù)據(jù)
actions:既然mutations只能處理同步函數(shù),我大js全靠‘異步回調(diào)’吃飯恤筛,怎么能沒有異步官还,于是actions出現(xiàn)了...
actions和mutations的區(qū)別
1.Actions?提交的是 mutations,而不是直接變更狀態(tài)叹俏。也就是說妻枕,actions會通過mutations,讓mutations幫他提交數(shù)據(jù)的變更粘驰。
2.Action 可以包含任意異步操作屡谐。ajax、setTimeout蝌数、setInterval不在話下
再來看一下實例:
<!DOCTYPE html>
<html lang="en">
<head>
? ? <meta charset="UTF-8">
? ? <meta name="viewport" content="width=device-width, initial-scale=1.0">
? ? <meta http-equiv="X-UA-Compatible" content="ie=edge">
? ? <title>Document</title>
</head>
<script src="./js/vuex.js"></script>
<script src="./js/vue2.0.js"></script>
<body>
? ? <div id="app">
? ? ? ? <hello></hello>
? ? </div>
</body>
<script>
? ? Vue.use(Vuex);
? var myStore =? new Vuex.Store({
? ? ? ? state:{
? ? ? ? ? ? //存放組件之間共享的數(shù)據(jù)
? ? ? ? ? ? name:"jjk",
? ? ? ? ? ? age:18,
? ? ? ? ? ? num:1
? ? ? ? },
? ? ? ? mutations:{
? ? ? ? ? ? //顯式的更改state里的數(shù)據(jù)
? ? ? ? ? ? change:function(state,a){
? ? ? ? ? ? ? ? //? state.num++;
? ? ? ? ? ? ? console.log(state.num += a);
? ? ? ? ? ? },
? ? ? ? ? ? changeAsync:function(state,a){
? ? ? ? ? ? ? ? console.log(state.num +=a);
? ? ? ? ? ? }
? ? ? ? },
? ? ? ? getters:{
? ? ? ? ? ? getAge:function(state){
? ? ? ? ? ? ? ? return state.age;
? ? ? ? ? ? }
? ? ? ? },
? ? ? ? actions:{
//設(shè)置延時
? ? ? ? ? ? add:function(context,value){
? ? ? ? ? ? ? ? setTimeout(function(){
//提交事件
? ? ? ? ? ? ? ? ? ? context.commit('changeAsync',value);
? ? ? ? ? ? ? ? },1000)
? ? ? ? ? ? }
? ? ? ? }
? ? });
? ? Vue.component('hello',{
? ? ? ? template:`
? ? ? ? ? ? ? ? <div>
? ? ? ? ? ? ? ? ? ? <p @click='changeNum'>姓名:{{name}} 年齡:{{age}} 次數(shù):{{num}}</p>
? ? ? ? ? ? ? ? ? ? <button @click='changeNumAnsyc'>change</button>
? ? ? ? ? ? ? ? </div>`,
? ? ? ? computed: {
? ? ? ? ? ? name:function(){
? ? ? ? ? ? ? ? return this.$store.state.name
? ? ? ? ? ? },
? ? ? ? ? ? age:function(){
? ? ? ? ? ? ? ? return this.$store.getters.getAge
? ? ? ? ? ? },
? ? ? ? ? ? num:function(){
? ? ? ? ? ? ? ? return this.$store.state.num
? ? ? ? ? ? }
? ? ? ? },
? ? ? ? mounted:function(){
? ? ? ? ? ? console.log(this)
? ? ? ? },
? ? ? ? methods: {
? ? ? ? ? ? changeNum: function(){
? ? ? ? ? ? ? ? //在組件里提交
? ? ? ? ? ? ? ? // this.num++;
? ? ? ? ? ? ? ? this.$store.commit('change',10)
? ? ? ? ? ? },
//在組件里派發(fā)事件 當(dāng)點擊按鈕時愕掏,changeNumAnsyc觸發(fā)-->actions里的add函數(shù)被觸發(fā)-->mutations里的changeAsync函數(shù)觸發(fā)
? ? ? ? ? ? changeNumAnsyc:function(){
? ? ? ? ? ? ? ? this.$store.dispatch('add', 5);
? ? ? ? ? ? }
? ? ? ? },
? ? ? ? data:function(){
? ? ? ? ? ? return {
? ? ? ? ? ? ? ? // num:5
? ? ? ? ? ? }
? ? ? ? }
? ? })
? ? new Vue({
? ? ? ? el:"#app",
? ? ? ? data:{
? ? ? ? ? ? name:"dk"
? ? ? ? },
? ? ? ? store:myStore,
? ? ? ? mounted:function(){
? ? ? ? ? ? console.log(this)
? ? ? ? }
? ? })
</script>
</html>
先整明白 context dispatch是什么東西:
context:context是與 store 實例具有相同方法和屬性的對象《ド。可以通過context.state和context.getters來獲取 state 和 getters饵撑。
dispatch:翻譯為‘派發(fā)剑梳、派遣’的意思,觸發(fā)事件時滑潘,dispatch就會通知actions(跟commit一樣一樣的)參數(shù)跟commit也是一樣的垢乙。
action的大體流程:1.在actions選項里添加函數(shù)(異步)并提交到對應(yīng)的函數(shù)(在mutation選項里)中??context.commit('changeAsync',value);
actions:{
? ? ? ? ? ? add:function(context,value){
? ? ? ? ? ? ? ? setTimeout(function(){
? ? ? ? ? ? ? ? ? ? context.commit('changeAsync',value);
? ? ? ? ? ? ? ? },1000)
? ? ? ? ? ? }
? ? ? ? }
2. 在組件里:?changeNumAnsyc:function(){this.$store.dispatch('add', 5);} ?將dispatch“指向”actions選項里的函數(shù)
3. 在mutations選項里,要有對應(yīng)的函數(shù)?changeAsync:function(state,a){console.log(state.num +=a);}
總結(jié):
各個類型的 API各司其職语卤,mutation 只管存追逮,你給我(dispatch)我就存;action只管中間處理粹舵,處理完我就給你钮孵,你怎么存我不管;Getter 我只管取眼滤,我不改的巴席。action放在了 methods 里面,說明我們應(yīng)該把它當(dāng)成函數(shù)來用(講道理诅需,鉤子函數(shù)也應(yīng)該可以的) mutation是寫在store里面的漾唉,這說明,它就是個半成品诱担,中間量毡证,我們不應(yīng)該在外面去操作它电爹。getter寫在了 computed 里面蔫仙,這說明雖然 getter我們寫的是函數(shù),但是我們應(yīng)該把它當(dāng)成計算屬性來用丐箩。