vuex管理狀態倉庫詳解

一.什麼是Vuex?

 Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。Vuex 也集成到 Vue 的官方調試工具 devtools extension,提供了諸如零配置的 time-travel 調試、狀態快照導入導出等高級調試功能。採用了全局單例模式,將組件的共享狀態抽離出來管理,使得組件樹中每個位置均可以獲取共享的狀態或者觸發行爲。
 那麼什麼是狀態呢?我把狀態理解爲在沒有使用vuex時,在當前組件中data內須要共用的數據爲狀態。
 vuex使得狀態或行爲成爲了共享的狀態,所共享的狀態或行爲能夠在各個組件中均可以訪問到,省去了子父或子子之間傳遞變量,提升了開發效率。css

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

 當咱們不使用vuex時,對於組件之間傳遞信息會較爲麻煩。vue

不使用vuex時

父子之間傳遞信息:

App.vue文件中:java

<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文件中:git

<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.jsgithub

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

兄弟組件Goods:ajax

<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:vuex

<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組件中的代碼:
在這裏插入圖片描述
點擊按鈕:在這裏插入圖片描述
     在這裏插入圖片描述
 上述爲兄弟組件之間的傳值,是否是感受到有點麻煩呢?初學vue組件傳值時,我也以爲這種方法很麻煩,vuex很好的解決了這個問題,愉快的編寫代碼。npm

使用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更容易了點呢?可是這才只是個很是淺很是淺的開始。下面進入正文!!!api

三.vuex的使用

vuex的安裝

 打開終端,輸入命令行npm install vuex --save進行下載vuex
在這裏插入圖片描述app

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應用核心管理倉庫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
    }
    
}

那麼對於以上的store咱們就簡單介紹完了,相信你們看完後對於vuex會有必定的理解。那麼這個時候咱們要想,是否是使用this.$store.state或this.$store.getters.xxx感到麻煩呢?下面咱們介紹另外一種引入state和getters的方式

輔助函數mapState和mapGetters

 對於上述的引用state和getters的方法是否是感到麻煩呢?使用mapState你將會感覺到便利。

//首先咱們須要先將輔助函數引入
import { mapGetters,mapState } from 'vuex'

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

以上就是對於vuex的詳解啦,但願可以幫助到你們對於vuex的理解,感興趣的化就點個讚唄!

相關文章
相關標籤/搜索