天天看點

vuex管理狀态倉庫詳解一.什麼是Vuex?二.不使用vuex時與使用vuex時的差别

一.什麼是Vuex?

 Vuex 是一個專為 Vue.js 應用程式開發的狀态管理模式。它采用集中式存儲管理應用的所有元件的狀态,并以相應的規則保證狀态以一種可預測的方式發生變化。Vuex 也內建到 Vue 的官方調試工具 devtools extension,提供了諸如零配置的 time-travel 調試、狀态快照導入導出等進階調試功能。采用了全局單例模式,将元件的共享狀态抽離出來管理,使得元件樹中每一個位置都可以擷取共享的狀态或者觸發行為。

 那麼什麼是狀态呢?我把狀态了解為在沒有使用vuex時,在目前元件中data内需要共用的資料為狀态。

 vuex使得狀态或行為成為了共享的狀态,所共享的狀态或行為可以在各個元件中都可以通路到,省去了子父或子子之間傳遞變量,提高了開發效率。

二.不使用vuex時與使用vuex時的差别

 當我們不使用vuex時,對于元件之間傳遞資訊會較為麻煩。

不使用vuex時

父子之間傳遞資訊:

App.vue檔案中:

<template>
  <div id="app">
      <Fruits :fruitList="fruitList"/>
  </div>
</template> 
<script>
import Goods from './components/Goods';
export default {
  name: 'App',
  components:{
    Fruits,
    Goods
  },
  data(){
    return{
      goodList:[
      {
        name:'doll',
        price:12
      },
      {
        name:'glass',
        price:10
      }
    ],
    }
  }
}
</script>
<style>
</style>           

Good.vue檔案中:

<template>
  <div class="hello">
      <ul>
        <li v-for="(good,index) in goodList" :key="index">
          name:{{good.name}}  number: {{good.number}} {{index}}
        </li>
      </ul>
  </div>
</template>

<script>
export default {
  props:['goodList'],
}
</script>
<style>

</style>           

兄弟之間傳遞資訊:

首先先建立一個js檔案作為兩兄弟之間傳輸的紐扣,這裡起名為msg.js

//建立并暴露vue
import Vue from 'vue';
export default new Vue           

兄弟元件Goods:

<template>
  <div>
        <button @click="deliver">點選</button>
  </div>
</template>

<script>
import MSG from '../msg';
export default {
  data(){
    return{
      msg:'hahah'
    }
  },
  methods:{
    deliver() {
        MSG.$emit('showMsg',this.msg)
    }
  }

}
</script>
<style>

</style>           

兄弟元件Fruits:

<template>
  <div>
      <div class="fruit">
          {{text}}
      </div>
  </div>
</template>
<script>
import MSG from '../msg';
export default {
    data(){
      return{
        text:''
      }
    },
    created(){
      this.getMsg()
    },
    methods:{
      getMsg(){
        MSG.$on('showMsg',(message)=>{
            this.text = message
        })
      }
    }
}
</script>
<style>
</style>           

在App元件中的代碼:

vuex管理狀态倉庫詳解一.什麼是Vuex?二.不使用vuex時與使用vuex時的差别

點選按鈕:

vuex管理狀态倉庫詳解一.什麼是Vuex?二.不使用vuex時與使用vuex時的差别

     

vuex管理狀态倉庫詳解一.什麼是Vuex?二.不使用vuex時與使用vuex時的差别

 上述為兄弟元件之間的傳值,是不是感覺到有點麻煩呢?初學vue元件傳值時,我也覺得這種方法很麻煩,vuex很好的解決了這個問題,愉快的編寫代碼。

使用vuex共享狀态資料

store.js中的配置:

import Vue from 'vue';   //引入vue
import Vuex from 'vuex';  //引入vuex

Vue.use(Vuex) //聲明使用Vuex

const state = {
    count:1,
    totalName:'total'
}

const store = new Vuex.Store({
    state
 })
 export default store           

App.vue中的配置:

<template>
  <div id="app">
      <Fruits>
      <div>--------------------------</div>
      <Goods>
  </div>
</template> 
<script>
import Fruits from './components/Fruits';
import Goods from './components/Goods';
export default {
  name: 'App',
  components:{
    Fruits,
    Goods
  }
}
</script> 

<style>

</style>
           

Good.vue中的配置

<template>
  <div>
    <div>我是Goods中的元件</div>
     <div>我們共同的數字:{{this.count}}</div>
    <div>我們共同的名字是 {{this.totalName}} </div>
  </div>
</template>
<script>
import {mapState} from 'vuex';  //引入輔助函數
export default {
    computed:{
      ...mapState(['count','totalName'])  //對象展開運算符
    } 
}
</script>
<style>

</style>
           

Fruits.vue

<template>
  <div>
    <div>我是Fruits中的元件</div>
    <div>我們共同的數字:{{this.count}}</div>
    <div>我們共同的名字是 {{this.totalName}} </div>
  </div>
</template>

<script>
import {mapState} from 'vuex';   //引入輔助函數
export default {
    computed:{
        ...mapState(['count','totalName'])   //對象展開運算符
    }
}
</script>

<style>

</style>           

  上述為使用vuex進行簡單的引用狀态資料值的例子,将資料放到state中進行管理,引入輔助函數和将state中的資料引入元件,在元件中進行調用,這種方法是不是比不使用vuex更容易了點呢?但是這才隻是個非常淺非常淺的開始。下面進入正文!!!

三.vuex的使用

vuex的安裝

 打開終端,輸入指令行

npm install vuex --save

進行下載下傳vuex

vuex管理狀态倉庫詳解一.什麼是Vuex?二.不使用vuex時與使用vuex時的差别

vuex的核心概念:

  • State:共享狀态,相當于元件中data中的資料,隻不過此時變成了全局變量。
  • Getter:基于state的派生狀态,相當于元件中的computed中的屬性。
  • Mutation:更改vuex中store共享狀态中的方法,通過送出mutation來去修改狀态,進行同步操作資料,通常用于action擷取異步資料,擷取通過commit送出資料給mutation,在mutation同步操作state中的資料。
  • action:支援異步操作,可用于異步擷取請求中的資料,并将擷取的資料同步commit送出給mutation,實作ajax異步請求資料,mutation将其資料同步到state中。
  • module:為了友善後期對于項目的管理,對于store中的state,mutation,action,getter進行分子子產品化管理。

    下面我們的介紹将會在Module規範中進行介紹。

    Module子子產品化管理

    對于子子產品管理我們需要建立核心化管理對象store起名為index.js将其他state,getter,mutations,actions。引入到該store子產品中,并将其暴露Store對象,下面為代碼部分。

    module結構

    vuex管理狀态倉庫詳解一.什麼是Vuex?二.不使用vuex時與使用vuex時的差别

vuex應用核心管理倉庫store

 下面為store的代碼,這裡的js我們取名為index.js,通過将state,mutations,actions,getters引入到store中,并暴露出store對象。

/*
    vuex最核心的管理對象store
*/
import Vue from 'vue';
import Vuex from 'vuex';

import state from './state';
import mutations from './mutations';
import actions from './actions';
import getters from './getters';

//聲明使用插件
Vue.use(Vuex)
//new 一個Vuex的對象,将state,mutation,action,getters配置到vuex的store中,友善管理資料
export default new Vuex.Store({    
    state,
    mutations,
    actions,
    getters,
})           

state狀态管理資料

 我們通常将需要進行管理的共享資料,放入state中,使其形似為全局變量,對于需要的元件進行引入該state狀态資料。下面為state中的代碼舉例:

/* 
    狀态對象
*/
export default{
    userInfo: {},  //使用者資訊
    count:1
}           

mutation-types

 使用常量來代替mutations事件類型是一件很常見的模式,将這些常量放進一個單獨的檔案,可以使你的代碼合作者對于你的代碼一目了然,增強了代碼的可閱讀性。下面上代碼,由于隻是例子,是以此時隻引入了一個方法。

/* 
    包含n個mutation的type名稱常量
*/
export const RECEIVE_USER_INFO = 'receive_user_info'   //接收使用者資訊           

actions的異步操作

 actions與其mutations類似,但其可以進行異步操作,且将異步操作擷取的資料送出給mutations,使得mutations更改state中的狀态資料,這裡常常用于擷取ajax請求中的資料(因為是異步),并将其擷取的資料送出給mutations得到state資料狀态的更新。這裡的發送ajax發送請求的代碼,這裡就不進行示範了,大家能夠了解,此時action中的資料是通過發送ajax請求來擷取的就行。此時也能展現出actions中可以進行異步操作。下面上代碼:

/* 
    通過mutation間接更新state的多個方法的對象
*/
import {
    RECEIVE_USER_INFO,      //引入在mutation-types定義的常量
} from './mutation-types';

import {
    reqUserInfo,
} from '../api';      //這裡引入發送ajax請求的方法

export default{
    // 異步擷取使用者資訊
    async getUserInfo({commit}){
    //引入發送請求資料的方法,異步等待擷取資料,并将其資料指派給result
        const result = await reqUserInfo() 
        //當擷取資料成功時,result.code會為0,失敗則為1,這裡用于判斷是否擷取狀态資料成功
        if (result.code === 0) {  
            const userInfo = result.data //擷取請求中的資料
            //通過commit将其方法,和請求後擷取的使用者資訊傳遞給mutation
            commit(RECEIVE_USER_INFO,{userInfo})  
        }
    }
}              

需要注意的是:在元件中應用下列方式來去調用vuex元件中的方法:

this.$store.dispatch('getUserInfo')           

mutations同步送出資料

 mutations用于更改state中的狀态邏輯的,且為同步更改state中的狀态資料。需要知道的是在vuex中隻能通過mutation來去修改state對象,可以通過擷取actions擷取到的資料去修改state,也可以在mutations子產品中直接定義方法來去更改狀态資料。通過mutations和上面的actions子產品大家也可以看出commit是用于mutation子產品中的。在元件中調用其mutation子產品的代碼為:

this.$store.commit('increment')            

下面上mutation子產品中的代碼:

/* 
    直接更新state的多個方法的對象
*/

import {
    RECEIVE_USER_INFO,
} from './mutation-types';

export default{
//方法中的第一個預設形參為state,也可以傳入額外的參數,
既mutation的載荷(playload)
    [RECEIVE_USER_INFO](state,{userInfo}){
        state.userInfo = userInfo
    },
    //不通過actions直接在mutation子產品中更改state狀态資料
    increment(state){
        state.count = 3
    }
}           

Getters對state進行加工

Getters相當于computed計算屬性,用于加工處理state狀态資料,有其兩個預設參數,第一個預設參數為state,第二個預設參數為getters。

在元件中調用該方法的代碼片段為:

this.$store.getters.totalCount()           

下面為Getters中的代碼片段:

/* 
    包含多個基于state的getter計算屬性的對象  
*/
export default{

    plusCount(state){
        return state.count + 1
    },
 //擷取state中狀态資料對象,和擷取getters子產品中plusCount資料
    totalCount(state,getters){
        return getters.plusCount + state.count
    }

}           

輔助函數mapState和mapGetters

//首先我們需要先将輔助函數引入
import { mapGetters,mapState } from 'vuex'

export default {
  computed: {
  // 使用對象展開運算符将 getter 混入 computed 對象中
    ...mapGetters(['plusCount','totalCount',])
  // 使用對象展開運算符将 state 混入 computed 對象中
    ...mapState(['userInfo','count'])
  }
}           

繼續閱讀