Vuex的初探與實戰小結

1.概述前端

每個 Vuex 應用的核心就是 store(倉庫)。「store」基本上就是一個容器,它包含着你的應用中大部分的狀態 (state)。vue

Vuex 和單純的全局對象有如下兩點不一樣:ajax

1.Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那麼相應的組件也會相應地獲得高效更新;2.你不能直接改變 store 中的狀態。改變 store 中的狀態的惟一途徑就是顯式地提交 (commit) mutation。這樣使得咱們能夠方便地跟蹤每個狀態的變化,從而讓咱們可以實現一些工具幫助咱們更好地瞭解咱們的應用vuex

**2.安裝使用 **npm

2.1.使用Vue-cli開發安裝vue包數組

cnpm install vuex --save

2.2.在src目錄下建立store文件夾並建立index.js以下(src/store/index.js)app

import Vue from 'vue'
import Vuex from 'vuex'
 
Vue.use(Vuex);
 
export default new Vuex.Store({
 state: {
 
 },
 getters: {
 
 },
 mutations: {
 
 },
 actions: {
 
 }
});

前端全棧學習交流圈:866109386,面向1-3經驗年前端開發人員,幫助突破技術瓶頸,提高思惟能力,羣內有大量PDF可供自取,更有乾貨實戰項目視頻進羣免費領取。異步

而後在src文件下的main.js中使用函數

import Vue from 'vue'
import App from './App'
import store from './store'
Vue.config.productionTip = false
 
 
new Vue({
 el: '#app',
 store,
 components: { App },
 template: '<App/>'
})

3.用法簡介工具

** 3.1.state**

state是保存共享數據的,如今改store/index.js以下:

state: {
  count:0
 },

在components目錄下建立Index.vue如:

<template>
 <div class="index">
  {{count}}
 </div>
</template>
 
<script>
 export default {
  name: "index",
  computed:{
   count(){
    return this.$store.state.count;
   }
  }
 }
</script>

前端全棧學習交流圈:866109386,面向1-3經驗年前端開發人員,幫助突破技術瓶頸,提高思惟能力,羣內有大量PDF可供自取,更有乾貨實戰項目視頻進羣免費領取。

結果以下: 咱們能夠經過組件的計算屬性來保存state裏面的值,那麼問題來了,若是store太多的話,咱們組件裏面的計算屬性豈不是成了這個樣子:

computed:{
 count(){
   return this.$store.state.count;
 },
  stateA(){
   return this.$store.state.stateA;
  },
  stateB(){
   return this.$store.state.stateB;
  }
}

這樣獲取共享狀態的數據也沒有什麼問題不過看起來仍是有大量的重複冗餘代碼,咱們可使用 mapState 輔助函數幫助咱們生成計算屬性,讓你少按幾回鍵:

當映射的計算屬性的名稱與 state 的子節點名稱相同時,咱們也能夠給mapState傳一個字符串數組。

import {mapState} from 'vuex'
 export default {
  name: "index",
  computed:{
   ...mapState(['count']),
  }
 }

小結:使用 Vuex 並不意味着你須要將全部的狀態放入 Vuex。雖然將全部的狀態放到 Vuex 會使狀態變化更顯式和易調試,但也會使代碼變得冗長和不直觀。若是有些狀態嚴格屬於單個組件,最好仍是做爲組件的局部狀態。

3.2.getter

有的時候咱們須要對共享狀態裏面的某一個屬性作一些處理後再使用,咱們能夠把數據獲取後再在組件的計算屬性中處理,舉個例子以下:

// store/index.js
state: {
  count:0,
  numbers:[0,1,2,3,4,5,6,7,8]
 },
// Index組件
<template>
 <div class="index">
  {{count}}
  <br>
  {{numbers.join()}}
 </div>
</template>
<script>
 import {mapState} from 'vuex'
 export default {
  name: "index",
  computed:{
   ...mapState(['count']),
   numbers(){
    return this.$store.state.numbers.filter((item)=>{
     return item>3;
    })
   }
  }
 }
</script>

前端全棧學習交流圈:866109386,面向1-3經驗年前端開發人員,幫助突破技術瓶頸,提高思惟能力,羣內有大量PDF可供自取,更有乾貨實戰項目視頻進羣免費領取。

結果以下: 那麼問題來了,若是多個組件都要作一樣的處理,咱們就須要把一份代碼複製到多個地方,顯然是不大合理的,因而有了getter,能夠理解爲組件裏面的計算屬性。示例以下:

/ store/index.js
getters: {
  filterNumbers(state){
   return state.numbers.filter((item)=>{
    return item>3;
   })
  }
 },
// Index組件
<template>
 <div class="index">
  {{count}}
  <br>
  {{filterNumbers.join()}}
 </div>
</template>
 
<script>
 import {mapState} from 'vuex'
 export default {
  name: "index",
  computed:{
   ...mapState(['count']),
   filterNumbers(){
    return this.$store.getters.filterNumbers;
   }
  }
 }
</script>

結果徹底同樣,咱們能夠根據this.$store.getters.屬性名來獲取getters,也能夠經過 mapGetters 輔助函數將 store 中的 getter 映射到局部計算屬性:

具體實現方式以下:

<template>
 <div class="index">
  {{count}}
  <br>
  {{filterNumbers.join()}}
  <br>
  {{antherNumbers.join()}}
 </div>
</template>
 
<script>
 import {mapState,mapGetters} from 'vuex'
 export default {
  name: "index",
  computed:{
   ...mapState(['count']),6
   ...mapGetters(['filterNumbers']),
   ...mapGetters({
    antherNumbers:'filterNumbers'
   })
  }
 }
</script>

若是用同一名字直接把數組做爲參數,若是想改一個名字,能夠傳入一個對象做爲參數,結果以下:

3.3.mutation

在組件內,來自store的數據只能讀取,不能手動改變,改變store中數據惟一的途徑就是顯示的提交mutations。Vuex 中的 mutation 很是相似於事件:每一個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler)。這個回調函數就是咱們實際進行狀態更改的地方,而且它會接受 state 做爲第一個參數。改變代碼以下:

// store/index.js
mutations: {
 add(state){
  state.count++;
 }
},
 
// Index組件
**
  <button @click="add">+</button>
**
  methods:{
   add(){
    this.$store.commit('add');
    console.log(this.count);
   }
**

連續點擊5次增長按鈕,發現count的值也改變了。固然,咱們也能夠傳參進去

// store/index.js
mutations: {
 add(state,n){
  state.count+=n;
 }
},
 
// Index組件
**
  <button @click="add">+</button>
**
  methods:{
   add(){
    this.$store.commit('add',10);
    console.log(this.count);
   }
**

觸發方法語句爲:this.$store.commit(方法名);也可使用輔助函數mapMutations代替:

methods:{
  ...mapMutations(['add']),
}

3.4.action

前面咱們講過,mutation有必須同步執行這個限制,咱們在業務需求中有時候須要在獲取ajax請求數據以後再操做或定時器操做數據,這些都屬於異步請求,要用actions來實現。具體實現以下:

// store/index.js
mutations: {
  changeCount(state){
   state.count=3000;
  },
 },
 actions: {
  changeCount3000s(context){
   setTimeout(()=>{
    context.commit('changeCount')
   },3000)
 
// Index組件
<button @click="changeCount3000s">點擊按鈕3s後count的值改變</button>
methods:{
 ...mapMutations(['add']),
  changeCount3000s(){
    this.$store.dispatch('changeCount3000s');
  }
 }

前端全棧學習交流圈:866109386,面向1-3經驗年前端開發人員,幫助突破技術瓶頸,提高思惟能力,羣內有大量PDF可供自取,更有乾貨實戰項目視頻進羣免費領取。

咱們在點擊按鈕3s後count的值改變爲3000,咱們能夠經過this.$store.dispatch(方法名)來觸發事件,也能夠經過輔助函數mapActions來觸發。

import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
  methods:{
   ...mapMutations(['add']),
   ...mapActions(['changeCount3000s'])
  }

學會以上幾個屬性的使用基本就能夠知足平時業務中的需求了,但使用Vuex會有必定的門檻和複雜性,它的主要使用場景是大型單頁面應用,若是你的項目不是很複雜,用一個bus也能夠實現數據的共享,可是它在數據管理,維護,還只是一個簡單的組件,而Vuex能夠更優雅高效地完成狀態管理,因此,是否使用Vuex取決於你的團隊和技術儲備。

相關文章
相關標籤/搜索