Vue管理系統前端系列二相關工具引入及封裝

發表於2020-08-20


sass-loader/vuex 等的引入說明

tips:vue-cli 4.x腳手架封裝度更高,配置起來簡單許多,旨在讓使用者把精力都放在編寫業務程式碼中

vue-cli 4.x在建立時已經選擇了相應依賴,因此專案建立好後,基本的依賴都有。不需要重複安裝。

引入 element

vue-cli 4.x 引入 element 可謂是相當的方便,只需要執行下方語句,即可引入element

vue add element

有兩個選項,根據需求選擇,

  • How do you want to import Element? Import on demand #這裡選擇的是按需引入。只引入需要的元件,以達到減小專案體積的目的。
  • Choose the locale you want to load zh-CN # 選擇載入環境,這裡選擇的是中文

需要使用什麼元件,在plugins下的 element.js 中新增對應的元件。以減小專案體積。

TIPS:此種方式會自動引入樣式

引入 axios

更多關於axios的資訊,請看我另一篇文章,傳送門

axios 是一個基於 Promise 用於瀏覽器和 nodejsHTTP 客戶端,專案與後端的請求互動需要使用到 axios,執行以下命令,安裝 axios 依賴。

npm i axios

1.基本使用

安裝完成後,可以直接在介面上引入 axios 然後使用 axios.get 就能直接發起 get 請求。

import axios from 'axios'

axios.get('url').then((data) => {
    console.log(data)
})

2.封裝使用

2.1 開發環境配置請求地址

首先在.env.development檔案中配置 需要發起 請求的地址,VUE_APP_BASE_RUL='https://www.fastmock.site/mock/37b157378200e4dbd5eecff887e20f81/lion/'

需要特別注意的是 .env.production.env.development檔案 引數說明:

  • NODE_ENV - 是 “development”、“production” 、"test"或者自定義的值。具體的值取決於應用執行的模式
  • BASE_URL - 會和 vue.config.js 中的 publicPath 選項相符,即你的應用會部署到的基礎路徑
  • 除了 NODEENV 和 BASE_URL,其他的環境變數必須以 VUE_APP 開頭
  • 專案中使用:process.env.環境變數名,eg:VUE_APP_BASE_URL

2.2 配置代理

然後,若要配置跨域處理的話,在vue.config.js檔案中新增訪問代理。

module.exports = {
    publicPath: process.env.NODE_ENV === 'production' ? '/' : '/',
    outputDir: 'dist', //預設輸出到該資料夾,生成時會自動刪除該檔案
    assetsDir: 'static',
    lintOnSave: true, // 是否開啟eslint儲存檢測
    productionSourceMap: false, // 是否在構建生產包時生成sourcdeMap
    chainWebpack: (config) => {
        config.resolve.alias.set('@', resolve('src')).set('views', resolve('src/views'))
        // config.optimization.runtimeChunk('single')
    },
    devServer: {
        host: 'localhost',
        port: '8080',
        hot: true,
        open: true,
        overlay: {
            warning: false,
            error: true,
        },
        proxy: {
            [process.env.VUE_APP_BASE_RUL]: {
                target: process.env.VUE_APP_BASE_RUL,
                changeOrigin: true,
                secure: false,
                pathRewrite: {
                    ['^' + process.env.VUE_APP_BASE_RUL]: '',
                },
            },
        },
    },
}

2.3 新增介面相關檔案

相關檔案說明:

    1. config.js:axios 預設配置,請求基本 url。
    1. axiosHttp.js:二次封裝 axios 模組,包含攔截器等資訊。
    1. index.js:請求介面彙總模組,聚合模組 API。 在 main.js 檔案中按外掛引入

在 src/api 資料夾下新增 config.js配置檔案

const baseUrl = process.env.VUE_APP_BASE_RUL
export default {
    method: 'get',
    // 基礎url字首
    baseURL: baseUrl,
    // 請求頭資訊
    headers: {
        'Content-Type': 'application/json;charset=UTF-8',
    },
    // 引數
    data: {},
    // 設定超時時間
    timeout: 10000,
    // 返回資料型別
    responseType: 'json',
}

在 src/api 資料夾下新增 axiosHttp.js配置檔案

import axios from 'axios'
import qs from 'qs'
import router from '@/router'
import config from './config'
import { Message } from 'element-ui'

axios.defaults.timeout = config.timeout
axios.defaults.headers = config.headers
axios.defaults.baseURL = config.baseURL

// 請求攔截器
axios.interceptors.request.use(
    (config) => {
        // 觸發loading效果
        //判斷是否存在token,如果存在,則在header上加上token
        // let token = getStore('token')
        // if (token) {
        //     config.headers.common['token'] = token
        // }
        if (config.method == 'post' || config.method == 'put') {
            //將資料轉成string
            config.data = JSON.stringify(config.data)
        } else if (config.method == 'get') {
            //&& browser.isIE
            //給Get新增時間戳 解決IE快取問題
            let symbol = config.url.indexOf('?') >= 0 ? '&' : '?'
            config.url += symbol + '_=' + Date.now()
            config.data = qs.stringify(config.data)
        }
        return config
    },
    (err) => {
        // 關閉loading
        // 失敗提示
        return Promise.resolve(err)
    }
)

// 響應攔截器
axios.interceptors.response.use(
    (response) => {
        // 關閉loading
        if (!response || !response.data || !response.data.success) {
            // 失敗提示
        } else if (response.data.data && response.data.code == 200) {
            // 成功處理
        }
        if (response.data) {
            switch (response.data.code) {
                case 401:
                    // 返回 401 清除token資訊並跳轉到登入頁面
                    // store.commit('LOGOUT')
                    Message.error('登入已失效,請重新登入')
                    setTimeout(function () {
                        router.replace({
                            path: '/login',
                            // 登入成功後跳入瀏覽的當前頁面
                            query: { redirect: router.currentRoute.fullPath },
                        })
                    }, 1500)
                    break
                case 402:
                    //402無許可權操作
                    Message.error('無許可權操作')
                    return new Promise(() => {}) //外部不會再處理
                    break
            }
        }
        return response
    },
    (err) => {
        // 關閉loading
        // 提示異常
        let errMessage = ''
        if (err && err.response) {
            switch (err.response.status) {
                case 400:
                    errMessage = '請求錯誤'
                    break
                case 401:
                    errMessage = '未授權,請登入'
                    break
                case 403:
                    errMessage = '拒絕訪問'
                    break
                case 404:
                    errMessage = `請求發生錯誤`
                    // err.response.config.url
                    break
                case 408:
                    errMessage = '請求超時'
                    break
                case 500:
                    errMessage = '伺服器內部錯誤'
                    break
                case 501:
                    errMessage = '服務未實現'
                    break
                case 502:
                    errMessage = '閘道器錯誤'
                    break
                case 503:
                    errMessage = '服務不可用'
                    break
                case 504:
                    errMessage = '閘道器超時'
                    break
                case 505:
                    errMessage = 'HTTP版本不受支援'
                    break
                default:
                    errMessage = '伺服器開小差了,請稍後再試'
            }
        }
        Message.error(errMessage)
        //外部不會再處理
        return new Promise(() => {})
    }
)
export default {
    Get(url, params = {}) {
        return new Promise((resolve, reject) => {
            axios
                .get(url, { params })
                .then((res) => {
                    resolve(res.data)
                })
                .catch((error) => {
                    reject(error)
                    //resolve(error)
                })
        })
    },
    Post(url, params = {}) {
        return new Promise((resolve, reject) => {
            axios
                .post(url, params)
                .then((res) => {
                    resolve(res.data)
                })
                .catch((error) => {
                    reject(error)
                    //resolve(error)
                })
        })
    },
    Delete(url, params = {}) {
        return new Promise((resolve, reject) => {
            axios
                .delete(url, params)
                .then((res) => {
                    resolve(res.data)
                })
                .catch((error) => {
                    reject(error)
                    //resolve(error)
                })
        })
    },
    Put(url, params = {}) {
        return new Promise((resolve, reject) => {
            axios
                .put(url, params)
                .then((res) => {
                    resolve(res.data)
                })
                .catch((error) => {
                    reject(error)
                    //resolve(error)
                })
        })
    },
}

在 src/api/modules 資料夾下新增 user.js檔案

import axios from '@/api/axiosHttp'

export const login = (params) => {
    return axios.Post('/login', params)
}

export const test = () => {
    return axios.Get('/test')
}

在 src/api 資料夾下新增 index.js檔案

/*
 * 介面統一整合模組
 */
import * as user from '@/api/modules/user'

// 預設全部匯出
export default {
    ...user,
}

可以在 main.js 中將所有的 介面都掛在到原型鏈上,也可以介面引入需要的介面

  1. 需要使用原型鏈方式的,程式碼如下:
# main.js 檔案
import api from '@/api'
Vue.prototype.$api = api

# app.vue 檔案
methods: {
    loginFunc() {
        this.$api.login({ username: 'admin', password: '123456' }).then((data) => {
            this.$message({
                type: 'success',
                message: JSON.stringify(data),
            })
        })
    },
},
  1. 單個介面引入需要的介面
# app.vue 檔案
import { login } from '@/api/modules/user'
export default {
    name: 'app',
    components: {
    },
    data() {
        return {}
    },
    methods: {
        loginFunc() {
            console.log(login)
            // console.log(this.$api.user.login)
            login({ username: 'admin', password: '123456' }).then((data) => {
                this.$message({
                    type: 'success',
                    message: JSON.stringify(data),
                })
            })
        },
    },
}

原文地址:http://book.levy.net.cn/doc/frontend/uiframe/utils_import.html

相關文章