Vuex的基本原理和簡單使用


什么是Vuex,有什么用?

Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。

普通的Vue狀態自管理在遇到多個視圖共同依賴同一狀態,或者會改變同一狀態時,會遇到難以管理,難以維護的麻煩。為了解決這個麻煩,Vue官方基於全局單例模式提供了Vuex狀態管理框架。

在Vuex框架中,Vue視圖,狀態,數據之間的關系如下圖所示:

image

什么時候應該使用Vuex,什么時候不要使用?

如果您不打算開發大型單頁應用,使用 Vuex 可能是繁瑣冗余的。確實是如此——如果您的應用夠簡單,您最好不要使用 Vuex。一個簡單的 store 模式就足夠您所需了。但是,如果您需要構建一個中大型單頁應用,您很可能會考慮如何更好地在組件外部管理狀態,Vuex 將會成為自然而然的選擇。

如何使用Vuex

創建一個Vuex的狀態管理倉庫

  1. 安裝Vuex框架:
    我們通過如下命令為Vue項目中添加Vuex框架
npm i Vuex

如下圖所示:
image
2. 在main.js中引入Vuex框架,並通過use命令加載到Vue中

import Vuex from 'vuex'
Vue.use(Vuex)
  1. 創建一個store倉庫,並把store倉庫注冊到Vue全局中;store倉庫包含state(單一狀態樹,提供響應式數據),getters(store的計算屬性),mutations(改變store狀態的方法),actions(處理異步操作,觸發mutation)
    image
const store = new Vuex.Store({
  state:{
  },
  mutations:{
  },
  actions:{
  },
  getters:{
  }
})

new Vue({
  store,
  render: h => h(App),
}).$mount('#app')

mutations

更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。Vuex 中的 mutation 非常類似於事件:每個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler)。這個回調函數就是我們實際進行狀態更改的地方,並且它會接受 state 作為第一個參數.

你不能直接調用一個 mutation handler。這個選項更像是事件注冊:“當觸發一個類型為 increment 的 mutation 時,調用此函數。”要喚醒一個 mutation handler,你需要以相應的 type 調用 store.commit 方法

actions

Action 類似於 mutation,不同在於:

  1. Action 提交的是 mutation,而不是直接變更狀態。
  2. Action 可以包含任意異步操作。
  3. Action的分發使用關鍵字
  1. 為store倉庫創建單一狀態樹State,並創建mutations方法修改state
const store = new Vuex.Store({
  state:{
    count:0
  },
  mutations:{
    increment(state,n){
      state.count+=n
      console.log(state.count)
    }
  },
  actions:{
  },
  getters:{
      
  }
})
  1. 到此為止,Vue中的組件就可以使用store狀態倉庫了。因為在main.js中,我們通過new Vue將store倉庫注冊到Vue全局中,所以我們在模板中可以通過this.$store的方式獲取到我們store倉庫。下面的示例展示了通過組件的計算屬性computed定義count變量並通過模板語法展現store狀態倉庫中的count值。
<template>
  <div id="app">
    {{count}}
  </div>
</template>

<script>

export default {
  name: 'App',
  components: {
    
  },
  computed:{
    count(){
      return this.$store.state.count
    }
  },
  methods:{
  }
}

效果如下:
image
6. 我們當然可以修改store的count值。我們先采用以前的模板事件來修改。

<template>
  <div id="app">
    {{count}}
    <input type="button" @click="handleClick" value="Count++" />
  </div>
</template>

<script>

export default {
  name: 'App',
  components: {
    
  },
  computed:{
    count(){
      return this.$store.state.count
    }
  },
  methods:{
    handleClick(){
      return this.$store.state.count++;
    }
  }
}
</script>

效果如下:
image
7. 但是Vue並不鼓勵我們采用這樣的方式來修改store的count值。這樣管理依然不方便,很有可能造成混亂。按照上面對mutations的介紹,我們可以猜到Vuex鼓勵我們通過mutations對store的state進行修改,這樣我們對state的修改過程才會被Vuex記錄下來。我們先前在初始化state時,同步初始化了mutations:我們創建了一個叫increment的方法,現在我們只需要調用這個方法即可。每一個mutations中的方法本質都是一個回調函數,處理sate狀態的邏輯都包含在里面,接收state參數。mutations方法可以多接收一個額外參數(提交荷載),如果希望傳入多個數據,則應該組織成對象再傳入(示例中僅僅是一個簡單的number)

mutations:{
    increment(state,n){
      state.count+=n
      console.log(state.count)
    }
  },
  1. Vuex中的mutations方法不能被直接調用,必須被actions或模板以commit的形式調用。我們先嘗試使用模板直接commit的形式調用(假設我們沒有異步操作需要處理,完全可以繞過actions)
<template>
  <div id="app">
    {{count}}
    <input type="button" name="count2" @click="$store.commit('increment',2)" value="Count+2" /> 
  </div>
</template>

<script>

export default {
  name: 'App',
  components: {
    
  },
  computed:{
    count(){
      return this.$store.state.count
    }
  },
  methods:{
  }
}
</script>

<style>
</style>

  1. 我們通過click事件直接對store進行了commit操作,commit調用時傳入了兩個參數,第一個是回調函數名:increment,另一個是提交荷載:一個整數;效果如下:
    image
  2. 到此為止,我們一直是使用的Vue組件的compute屬性展示的sotre。如果有多個組件需要用到此屬性,我們要么復制這個函數,或者抽取到一個共享函數然后在多處導入它——無論哪種方式都不是很理想。先前介紹過:getters是sotre的computer,那么我們完全可以在sotre的getters中處理展示邏輯。
const store = new Vuex.Store({
  state:{
    count:0
  },
  mutations:{
    increment(state,n){
      state.count+=n
      console.log(state.count)
    }
  },
  actions:{
  },
  getters:{
    doubleCount(state){
      return state.count * 2
    }
  }
})
<template>
  <div id="app">
    {{$store.getters.doubleCount}}
    <input type="button" name="count2" @click="$store.commit('increment',2)" value="Count+2" /> 
  </div>
</template>

<script>

export default {
  name: 'App',
  components: {
  },
  computed:{
  },
  methods:{
  }
}
</script>

<style>
</style>

效果如下:
image
11. 我們一直還沒有使用到store的actions。根據官網描述,actions與mutation很像,不同的是用來觸發(commit)mutation而不是直接修改狀態,最重要的是我們可以在actions中處理異步邏輯,調用遠程API等等(如下示例中,利用模擬異步等待);前台調用是使用dispatch關鍵字調用。

const store = new Vuex.Store({
  state:{
    count:0
  },
  mutations:{
    increment(state,n){
      state.count+=n
      console.log(state.count)
    }
  },
  actions:{
    increment(state,n){
      setTimeout(() => {
        state.commit('increment',n)
      },1000);
    }
  },
  getters:{
    doubleCount(state){
      return state.count * 2
    }
  }
})
<template>
  <div id="app">
    {{$store.getters.doubleCount}}
    <input type="button" name="count1" @click="$store.dispatch('increment',3)" value="Count+3" /> 
  </div>
</template>

<script>

export default {
  name: 'App',
  components: {
    
  },
  computed:{
  },
  methods:{
  }
}
</script>

<style>
</style>

效果如下:
image

組件調用Vuex關鍵字的方法總結

image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM