開發與維運

VueX 的使用,小白一定要看!

今天主要解決:

1. 什麼是vuex?
2. 為什麼要用到vuex?
3. 怎麼用?

文字比較多,不要嫌繁瑣,跟這練習一遍就會了,博主可是一個字一個字寫上的。

我們都知道,在做項目時,頁面與頁面之間要用到傳值和通信,都清楚父子通信,兄弟間通信等等。。。
但是有複雜的項目,可能會嵌套很多層,這樣一層一層的傳值,很麻煩!不光是對代碼質量造成了影響,也對代碼運行的性能造成了影響,甚至會造成難以排查的bug。

之前給幾個小白同學講個例子:
小朋友想要零花錢,會先和媽媽要,媽媽沒有,就去和爸爸要,爸爸把零花錢給了媽媽,媽媽再給了小朋友。
這個就很麻煩了,解決辦法,不如直接爸爸把零花錢放在一個指定的位置,誰要,誰就去那個位置拿,這樣就方便多了。

所以,vuex就是那個指定的地方,官方給起了個很專業的名字,叫:狀態管理模式,說白了,就是一個統一存放狀態的地方,誰用裡邊的值都可以取到,無論頁面的層次多深,不用擔心拿不到的問題,這樣解決複雜通信或傳值的問題就很方便了。

用到的地方也有很多:比如頁面切換後再回來,依然顯示上次搜索條件的結果,或n個組件同時共享一個狀態等等……

這些理解了,前兩個問題【什麼是vuex/為什麼要用到vuex】自然就迎刃而解了,接下來講一下vuex的實現原理,我們先來附上一張第一眼難以理解的官方圖片

image

相信很多小白看完這張圖片後根本不理解,沒關係,我舉例說一下:

比如有一個A頁面顯示了“100”這個數字,並且我可以隨意更改,但是需求上,其他BCD三個頁面也要顯示同樣的數字,這個字段改成什麼,就顯示什麼,要求就是要顯示的數字一模一樣。

那麼我就要有個地方,來放這個數據,我們先創建一個js文件,在裡邊定義一個對象,起名叫state,這個state專門定義這個數據的

const state={
    name : 100
}

然後所有頁面都可以顯示出這個name,顯示後還要有一個可以改的地方,我們同樣,在這個js文件中,在定義一個可以寫方法的對象叫mutations,它裡邊專門放方法,如下:

const mutations ={
    addNumber(){
        state.name+=100
    },
    miunNumber(){
        state.name-=100
    }
    }

文件中我寫了一個方法叫addNmuber,這個名字隨便起,我每次調用這個方法,就可以增加100,這樣就實現了所有頁面顯示的數字,都會增加。
這個mutations中所寫的方法,vue要求必須要是同步的,所以這裡都寫同步的方法,比如加100,或減100,或變顏色等需求都屬於同步方法。這樣也就是mutations控制了state中某個值的改變。

回到官網圖,看下圖中上邊還有一個actions,actions和mutations是一樣的寫法,區別在於,actions中要寫異步的方法,比如要調用某個異步接口,可以寫在這個當中,比如高德地圖和百度地圖的接口,就是異步請求,頁面中要引入一個地圖組件,很多頁面都公用,就可以寫在這個當中。

那麼這個異步方法actions有什麼用?如果有需求,說必須等待這個接口成功返回一個數值後,再改變state中的值,這時就需要actions中調用一個接口,接口返回後,調用mutations中的方法,來改變state中的值。

const actions = {
actionsAddNumber(context){
  this.axios.get('/接口名').then(()=>{
        context.commit('addNumber')
    })
   }, 
 }

actionsAddNumber名字隨便起,它接收一個context參數。其中調用了異步方法,成功用,利用commit觸發了mutations中的addNumber方法。
實戰當中,我們可以利用ES5的結構賦值,改變一下代碼,直接提取context參數中的commit使用,如下:

const actions = {
  // 結構賦值提取commit
actionsAddNumber({commit}){
  this.axios.get('/接口名').then(()=>{
      // 直接使用commit
        commit('addNumber')
    })
   }, 
 }

那麼在vue頁面使用store.dispatch觸發action中的方法:
this.$store.dispatch('actionsAddNumber')

不過注意的是,非大型項目actions並不是必須要用到的,一般state和mutations已足夠我們使用。官網也建議,非必須情況下,不建議使用vuex,因為我們需要下載,還要引入,在文件大小和加載上,都是會受到影響的。

回過頭來看官網的圖片,或許,你就理解了,若面試問到,說一下vuex的實現原理,就按照這個理解,按照官網的圖說:
頁面中的組件,通過dispatch,來調用actions方法異步加載,成功後,通過commit觸發mutations中的某個方法,來改變state中的某個值,這就是原理,最好再加上自己的理解說出來。

接下來說下vuex的用法:

創建項目時,vuex不會自帶,因為不是每個項目都需要vuex,所以我們需要下載

創建一個store文件夾,這個名字自己隨意起,規範一些起個storeimage

文件夾中放入一個js文件,例如:store.js。

文件中引入vuex,並創建出state、mutations即可(getters本文暫時不講)。

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

// 定義數據
// state在vuex中是用於儲存數據的
const state={
    name : 100
}

// 定義方法 mutation同步
// mutations 裡面方的是方法,主要用於改變state中的數據源
const mutations ={
    addNumber(){
        state.name+=100
    },
   }
  
// 實例化 Vuex.store,用到什麼引什麼,用到actions就引入actions,用到getters就引入getters,本文只用到這兩個
const store = new Vuex.Store({
    state,
    mutations
})

export default store;

搞定,vuex建立完成,就這麼簡單的一個vuex文件寫完了,接下來vue頁面文件中該使用這個了

首先我們需要找到目錄中main.js中引入vuex,把文件目錄引入,main.js是什麼,不懂的小白要去查查。

import Vue from 'vue'
import router from './router'
import store from './store/store'

new Vue({
  el: '#app',
  router, // 這個要使用
  store, // 這個也要使用
  components: { App },
  template: '<App/>'
})

使用很簡單,因為我們在上邊的store中實力化了這幾個方法(看上邊註釋),所以我們就需要用this.$store來進入這個文件中,那麼我想在頁面中顯示state中的數字100,如下寫法:

<div>{{this.$store.state.name}}</div>

任何一個頁面都可以這樣引用,引入一個,顯示一個。改變值的方法如下:

<button @click="add">增加100</button>
methods:{
    add(){
       this.$store.commit('addNumber')
      },
     }

點擊按鈕,就會增加數字了,並且改變一個,所有頁面上的這個屬性,也會跟著改變,多加練習和理解。

當然,我們可以向mutations中,傳入數值:

mutations: {
  // 兩個參數,一個是state,一個是參數n(也叫payload載荷)
  addNumber(state, n) {
    state.name+= n
  }
}
this.$store.commit('addNumber', 100)

這樣就是非固定的寫法,可以傳入你想要的參數值。

avillin筆記:

1. 能改變state的方法是mutations。
2. 頁面中用this.$store.state來獲取到state中的某個值。
3. 頁面中使用this.$store.commit來調用vuex中mutations裡的某個方法。
4. 頁面中使用this.$store.dispatch來調用vuex中actions裡的某個方法。

Leave a Reply

Your email address will not be published. Required fields are marked *