前言
如果你在使用Vue.js,肯定有很多元件之間相互傳遞引數的經歷。當遇到父子元件需要通訊的時候,我們經常用的方法是傳遞引數。其實除了傳遞引數的方式,我們還可以結合業務需要考慮是否用Vuex去解決。
Vuex是什麼?
官方文件的定義:Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式。它採用集中式儲存管理應用的所有元件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。
狀態管理模式、集中式儲存管理初次瞭解的話感覺有點難以理解,我們通過官方文件中提供的這張圖加深下理解。
Vuex是一種設計思想。每一個Vuex應用的核心就是Store(倉庫)。元件的狀態和資料都放到一個統一的記憶體空間state去管理,state的資料對映到元件上,當元件的資料發生變化時,通過Dispatch Actions或者直接Commit Mutations的方法修改state。我們不能直接改變state中的狀態。改變state中狀態的唯一途徑就是顯式的提交(Commit)Mutations。這樣使得我們可以方便的追蹤每一個狀態的變化,從而使我們能夠實現一些功能幫助我們更好的瞭解我們的應用。state修改後反映到元件上,形成閉環。當以往父子元件通訊的時候,我們通常會採用props+emit的方式。vuex適合更為複雜的使用場景。比如:
- 解決多個關聯度比較低的兄弟元件之間的狀態共享
- 解決路由間跳轉複雜的引數傳遞
實際應用
首先我們需要在開發環境中安裝Vuex:小編最近在做一個專案的填寫釋出頁面的功能,簡化來說就是從first頁面填寫資訊後,點選跳轉到second頁面,同時傳入first頁面中填寫的資訊。那麼如何用Vuex的方式實現呢?
npm install vuex --save
複製程式碼
然後在專案的src目錄下增加store資料夾,目錄如下
其中:- index.js:入口檔案
- state.js:儲存狀態。也就是變數。
- getters.js:派生狀態。也可以理解為set、get中的get。有兩個可選引數,state、getters分別可以獲取state中的變數和其它getters。和vue中的computed類似。
- mutations.js:提交狀態修改。可以理解為set、get中的set。每一個mutation都有一個字串的事件型別和回撥函式。第一個引數預設為state。vuex中唯一修改state的方式,不支援非同步操作。和vue中的methods類似。
- mutation-types.js:儲存於mutations相關的字串常量,方便檢測和管理。
- actions.js:和mutations類似。支援非同步操作,也可以是對mutations的封裝。
state.js 示例:
const state = {
userInfo: {}
};
export default state;
複製程式碼
userinfo 存放我們需要提交的資訊
mutation-types.js 示例:
export const SET_USERINFO = 'SET_USERINFO';
複製程式碼
mutation.js 示例:
import * as types from './mutation-types'
const mutations = {
[types.SET_USERINFO](state, userInfo) {
state.userInfo = userInfo;
}
}
複製程式碼
是一個物件,裡面存放一些方法,方法名就是mutation-types裡存放的常量名,第一個引數對應的是state.js檔案中的state;第二個引數是提交的引數。
getters.js 示例:
export const userInfo = state => state.userInfo;
複製程式碼
獲取state的狀態到元件。
index.js入口檔案配置,元件Vuex示例:
import Vue from 'vue'
import Vuex from 'vuex'
import * as actions from './actions'
import * as getters from './getters'
import state from './state'
import mutations from './mutations'
import createLogger from 'vuex/dist/logger'
Vue.use(Vuex)
// 開發環境為true,生產環境為false
const debug = process.env.NODE_ENV !== 'production'
export default new Vuex.Store({
actions,
getters,
state,
mutations,
plugin: debug ? [createLogger()] : []
})
複製程式碼
最後再將store例項注入main.js裡的vue例項中:
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
複製程式碼
完成這些基本的配置之後,接下來我們就要到專案中的呼叫了。Vuex為我們提供了一系列的語法糖:mapMutations,mapGetters,mapActions,省去了繁瑣的操作。我們可以直接按照vue呼叫methods和computed的方式去呼叫。
首先我們看下第一步first.vue的部分: template:
<template>
<div class="page">
<div>姓名: <input type="text" v-model="name"></div>
<div>年齡: <input type="text" v-model="age"></div>
<div>
<button @click="jumpToNextPage">下一頁</button>
</div>
</div>
</template>
複製程式碼
script:
import { mapMutations, mapActions } from "vuex";
export default {
data() {
return {
name: '張三',
age: '20',
personInfo: {}
};
},
methods: {
jumpToNextPage() {
this.personInfo.name = this.name;
this.personInfo.age = this.age;
this.$router.push({
path: `/second/`
});
this.setInfo(this.personInfo);
},
...mapMutations({
setInfo: 'SET_USERINFO'
})
}
};
複製程式碼
我們在這一步獲取使用者填寫的資訊提交到mutations。
首先我們需要從vuex引入mapMutations去操作state的變化。根據文件提供的方法,在methods裡通過擴充套件運算子的方式呼叫。我們在mapMutations裡需要做一個對映,setInfo對應的是mutation-types裡的常量SET_USERINFO。然後在點選跳轉到下一頁按鈕的時候執行this.setUser()這個方法,並且傳入資訊引數。
修改mutations之後,接下來就是在第二頁獲取state的變化了。
接下來我們來看second.vue的部分:template:
<template>
<div class="page">
姓名:{{userInfo.name}}
年齡:{{userInfo.age}}
</div>
</template>
複製程式碼
script:
import { mapGetters } from "vuex";
export default {
data() {
return {
};
},
computed: {
...mapGetters(["userInfo"])
},
created() {
console.log(this.userInfo);
},
methods: {
}
};
複製程式碼
第一步我們同樣需要從vuex中引入mapGetter。然後在computed中,同樣按照擴充套件運算子的方式引入需要得到的資料。此處userInfo對應的是getter.js中定義的userInfo。
這樣我們就通過vuex完成了從修改提交資料到獲取資料的整個過程。
剛才的部分我們是直接提交mutations,現在我們再來看下如何通過actions來提交mutations的變化。
actions.js 示例:
import * as types from './mutation-types';
export const actionsSetUserInfo = function ({ commit, state }, userInfo) {
commit(types.SET_USERINFO, userInfo);
}
複製程式碼
引入mutation-types之後,定義提交mutation的函式,actionSetUserInfo。commit和state是預設引數,userInfo是修改的引數資料。
此時first.vue修改為:
import { mapMutations, mapActions } from "vuex";
export default {
data() {
return {
name: '張三',
age: '20',
personInfo: {}
};
},
methods: {
jumpToNextPage() {
this.personInfo.name = this.name;
this.personInfo.age = this.age;
this.$router.push({
path: `/second/`
});
this.actionsSetUserInfo(this.personInfo);
},
...mapActions([
'actionsSetUserInfo'
])
}
};
複製程式碼
這樣,actions.js 裡actionSetUserInfo就被執行。通過commit mutation修改state中的使用者資訊。
結束語
簡單理解Vuex就是把元件之間需要共享的變數,全部儲存到一個物件裡,然後這個物件放在頂層元件中供其他元件使用。只不過我們需要按照Vvuex指定的規則對這些資料的存和取。
初次發文,僅是個人的一些理解,歡迎留言批評指正。