Vue開發庫存管理前端頁面時一些小經驗記錄

WangQingye發表於2018-04-16

全域性封裝

場景是在專案中很多地方都需要用到相同的函式,例如

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實現全域性請求載入動畫

場景是希望在所有請求的時候新增上載入動畫。

首先遇到的問題是,載入動畫應該掛載在哪裡?某個元件中?這裡需要根據具體的場景看,如果你的是多元件多頁面,那麼每一個全新的頁面都需要新增一個載入動畫,如果是一個單頁面應用,可以建議新增在最外層的父元件上。例如本專案中的頁面結構:

Vue開發庫存管理前端頁面時一些小經驗記錄

上方導航欄是在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');
複製程式碼

相關文章