今天主要解決:
1. 什麼是vuex?
2. 為什麼要用到vuex?
3. 怎麼用?
文字比較多,不要嫌繁瑣,跟這練習一遍就會了,博主可是一個字一個字寫上的。
我們都知道,在做項目時,頁面與頁面之間要用到傳值和通信,都清楚父子通信,兄弟間通信等等。。。
但是有複雜的項目,可能會嵌套很多層,這樣一層一層的傳值,很麻煩!不光是對代碼質量造成了影響,也對代碼運行的性能造成了影響,甚至會造成難以排查的bug。
之前給幾個小白同學講個例子:
小朋友想要零花錢,會先和媽媽要,媽媽沒有,就去和爸爸要,爸爸把零花錢給了媽媽,媽媽再給了小朋友。
這個就很麻煩了,解決辦法,不如直接爸爸把零花錢放在一個指定的位置,誰要,誰就去那個位置拿,這樣就方便多了。
所以,vuex就是那個指定的地方,官方給起了個很專業的名字,叫:狀態管理模式,說白了,就是一個統一存放狀態的地方,誰用裡邊的值都可以取到,無論頁面的層次多深,不用擔心拿不到的問題,這樣解決複雜通信或傳值的問題就很方便了。
用到的地方也有很多:比如頁面切換後再回來,依然顯示上次搜索條件的結果,或n個組件同時共享一個狀態等等……
這些理解了,前兩個問題【什麼是vuex/為什麼要用到vuex】自然就迎刃而解了,接下來講一下vuex的實現原理,我們先來附上一張第一眼難以理解的官方圖片
相信很多小白看完這張圖片後根本不理解,沒關係,我舉例說一下:
比如有一個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文件夾,這個名字自己隨意起,規範一些起個store
文件夾中放入一個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裡的某個方法。