全域性封裝
場景是在專案中很多地方都需要用到相同的函式,例如
this.$message({
type: 'success',
message: '提示語'
})
複製程式碼
如果出現次數過多,會造成書寫麻煩和程式碼複雜的情況。
解決思路:首先對函式進行抽象封裝,封裝後利用vue的mixin將其注入到各個vue中。
因為這裡的函式是大部分元件中都可能用到的,固利用vue的全域性混合。
-
新建一個global檔案:
const globalMethods = { methods: { tipSuccess(msg) { this.$message({ type: 'success', message: msg }) }, tipError(msg) { this.$message({ type: 'error', message: msg }) }, }, } export { globalMethods } 複製程式碼
-
在新建Vue的原型中利用mixin混入(main.js中,建立vue例項前):
Vue.mixin(globalMethods) 複製程式碼
-
任意vue中使用:
this.tipSuccess('成功提示') 複製程式碼
利用Vuex實現全域性請求載入動畫
場景是希望在所有請求的時候新增上載入動畫。
首先遇到的問題是,載入動畫應該掛載在哪裡?某個元件中?這裡需要根據具體的場景看,如果你的是多元件多頁面,那麼每一個全新的頁面都需要新增一個載入動畫,如果是一個單頁面應用,可以建議新增在最外層的父元件上。例如本專案中的頁面結構:
上方導航欄是在main.vue檔案中
下方是整體一個retouer-view,因此我們如果需要在所有頁面中新增載入動畫,可以直接寫在main.vue中
// 利用 elementUi的 v-loading
<template>
<div class="main" v-loading="this.$store.state.isRequesting">
<h3>
<i class="el-icon-menu"> </i> 舜新建材公司庫存管理系統</h3>
<keep-alive>
<router-view></router-view>
</keep-alive>
</div>
</div>
</template>
複製程式碼
上方程式碼中用到的this.$store.state.isRequesting就是我們實現全域性請求新增載入動畫的核心方法:利用vuex。
首先在新建store資料夾,index.js檔案:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
isRequesting: false,
isError: false
}
const mutations = {
saveIsRequesting(state, isRequesting) {
state.isRequesting = isRequesting;
},
saveIsError(state, isError) {
state.isError = isError;
},
}
const actions = {
setIsRequesting({
commit
}, isRequesting) {
commit('saveIsRequesting', isRequesting);
},
setIsError({
commit
}, isError) {
commit('saveIsError', isError);
},
}
export default new Vuex.Store({
state,
actions,
mutations
})
複製程式碼
上方程式碼的作用是新建了一個vuex的store,並且新增了兩個變數isRequestin和isError,分別用來標記是否需要提示正在請求(載入動畫),和是否請求出錯(提示伺服器錯誤),請求成功的提示場景比較多,所以需要在程式碼中自己實現。
記得在新建Vue例項的時候注入store:
new Vue({
el: '#app',
router,
store,
components: {
App
},
template: '<App/>'
})
複製程式碼
然後需要在自己封裝的請求函式中新增對這兩個變數的控制,本專案中是封裝的fetch.js:
// 關鍵程式碼
import store from '../store/index'
try {
// 在請求開始和結束時改變狀態
store.dispatch('setIsRequesting', true)
const response = await fetch(url, requestConfig);
const responseData = await response.json();
store.dispatch('setIsRequesting', false)
return responseData;
} catch (err) {
// 錯誤時改變狀態
store.dispatch('setIsRequesting', false)
store.dispatch('setIsError', true)
throw new Error(err)
}
複製程式碼
然後就可以在main中實現自動提示了。
自動載入動畫可以依賴ElementUI用v-loading實現:
v-loading="this.$store.state.isRequesting"
複製程式碼
伺服器錯誤提示需要自己手動實現,這裡利用了vue的computed和watch兩個鉤子函式:
computed: {
isError() {
return this.$store.state.isError;
}
},
watch: {
isError(newVal) {
if (newVal) {
this.tipError('伺服器出錯啦T.T');
// 顯示完後重置為false
this.$store.dispatch('setIsError', false);
}
}
}
複製程式碼
至此,我們的請求提示封裝就完成了,最終實現的效果是在任何請求發出時都會自動出現載入動畫,並且在請求出錯時提示伺服器錯誤,不需要在每一個請求的時候都try..catch了。
兄弟元件通訊
場景是兩個不相關的元件需要通訊,因為不是父子元件關係固不能利用this.$emit來傳遞。
固利用了vue提供的事件bus。
新建一個bus.js檔案
import Vue from 'vue';
export default new Vue();
複製程式碼
在需要監聽事件的元件中:
import Bus from '../util/bus';
Bus.$on('eventName', this.handle);
複製程式碼
觸發事件的元件中:
import Bus from '../util/bus';
Bus.$emit('refreshGoodList');
複製程式碼