Vue開發總結 及 一些最佳實踐 (已更新)

碼路芽子發表於2019-05-14

基本開發環境

vue-cli3 建立的專案,vscode 作為程式碼編寫工具 vscode外掛推薦:vscode 外掛配置

文章目錄

  1. 專案目錄結構介紹
  2. UI 框架選擇
  3. main,js 處理
  4. axios 請求二次封裝

1. 專案目錄結構簡介

├── public // index.html
├── src // 業務相關
│ ├── assets // 靜態檔案(css, images)
│ ├── components // 全域性元件
│ ├── layouts // 基礎樣式佈局
│ ├── plugin // 樣式及工具引入
│ ├── request // 請求配置
│ ├── router // 路由
│ ├── store // 全域性狀態管理
│ ├── utils // 工具檔案
│ ├── app.vue // 入口檔案
│ ├── main.js // 主要配置檔案
│ └── views // 頁面
├── .eslintrc.js // eslint 檢查配置
├── .env.release // 測試環境變數
├── .env.pre-build // 預發環境變數
└── vue.config.js // webpack 打包配置
複製程式碼

2. UI 框架選擇

經框架選擇驗證對比 element,iview,ant-design-vue 最終選擇 ant-design-vue,傳送門 vue.ant.design/docs/vue/in…

優點:
  1. 好看
  2. 文件清晰
  3. 使用方便,示例清晰
  4. bug少,元件使用順滑
  5. 效能較好,有單例測試

3. main.js 處理

main.js 作為操作入口,很多東西需要引入,程式碼體積過大,需要進行刪減

import Vue from 'vue'
import App from './App.vue'
import router from '@/router'
import store from '@/store'
import * as filters from '@/utils/filters'   // 全域性過濾器
import './plugin'    // 引入操作集合
import './assets/css/index.less'  // 樣式集合
Vue.config.productionTip = false

// 全域性過濾器
Object.keys(filters).forEach(key => {
  Vue.filter(key, filters[key])
})

// 非父子元件傳值公交車
Vue.prototype.$bus = new Vue()

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')
複製程式碼

這樣通過幾個集合,來分散引入各個模組

  1. 樣式模組 (import './assets/css/index.less' // 樣式集合)
@import './atom.less';
@import './global.less';
@import './reset.less';
複製程式碼
  1. 操作模組 (import './plugin/index.js' // 引入操作集合)
import './custom.js'
import './ant-design'
import './tools'

// tools.js
import Vue from 'vue'
import {
  getStorage,
  setStorage,
  rmStorage,
  setLocalStorage,
  getLocalStorage,
  rmLocalStorage
} from '@/utils/storage'
import moment from 'moment'
import 'moment/locale/zh-cn'
import api from '@/request/api'
import { isInvalid } from '@/utils/verify'
// 自定義元件
moment.locale('zh-cn')
// 請求介面
Vue.prototype.$api = api
// 驗證工具
Vue.prototype.$isInvalid = isInvalid
Vue.prototype.$moment = moment
// 儲存本地資料
Vue.prototype.$getStorage = getStorage
Vue.prototype.$setStorage = setStorage
Vue.prototype.$rmStorage = rmStorage
Vue.prototype.$getLocalStorage = getLocalStorage
Vue.prototype.$setLocalStorage = setLocalStorage
Vue.prototype.$rmLocalStorage = rmLocalStorage


// ant-design.js 
import Vue from 'vue'
import {
  Layout,
  Spin,
  Button,
  Icon,
  Avatar,
  Select,
  Drawer,
  Menu,
  Form,
  LocaleProvider,
  Dropdown,
  Divider,
  Modal,
  Input,
  Tooltip,
  notification,
  Popover,
  ConfigProvider,
  Pagination,
  Steps,
  Cascader,
  Row,
  Col
} from 'ant-design-vue'
import 'ant-design-vue/dist/antd.less'
Vue.use(Layout)
Vue.use(Spin)
Vue.use(Button)
Vue.use(Icon)
Vue.use(Avatar)
Vue.use(Select)
Vue.use(Popover)
Vue.use(Form)
Vue.use(Drawer)
Vue.use(Menu)
Vue.use(LocaleProvider)
Vue.use(Dropdown)
Vue.use(Modal)
Vue.use(Input)
Vue.use(Divider)
Vue.use(notification)
Vue.use(Pagination)
Vue.use(Tooltip)
Vue.use(ConfigProvider)
Vue.use(Steps)
Vue.use(Cascader)
Vue.use(Row)
Vue.use(Col)

複製程式碼

4. axios 請求二次封裝

axios 不過多介紹,上乾貨

  1. 新建檔案 axios
  2. 請求攔截器 根據自己業務需求,修改請求頭以及超時時間等
import axios from 'axios'
axios.interceptors.request.use(
  config => {
    // 判斷是否是提交檔案,還是常規請求
    if (config.data instanceof FormData) {
      config.headers = {
        'Content-Type': 'multipart/form-data' // 此處格式自定義
      }
    } else {
      config.data = JSON.stringify(config.data)
      config.headers = {
        'Content-Type': 'application/json', // 此處格式自定義
        token: getLocalStorage('token')
      }
    }
    config.withCredentials = true
    config.timeout = 5000    // 超時時間
    return config
  },
  error => {
    return Promise.reject(error)
  }
)
複製程式碼
  1. 響應攔截器 根據後臺返回資料,做些統一處理
// 新增響應攔截器
axios.interceptors.response.use(
  res => {
    let data = res.data
    if (res.statusCode !== 200) {
      if (data.failureReason === 4011 || data.failureReason === 4012) {
        console.log('需要重新登入')
      }
    } else {
      if (data.resultStates === 0) {
        return data
      } else {
        return Promise.reject(data)
      }
    }
  },
  error => {
    notification['error']({
      message: '提示',
      duration: 2,
      description: '後臺報錯'
    })
    // 對響應錯誤做點什麼
    return Promise.reject(error)
  }
)
複製程式碼
  1. 封裝get,post,並匯出
export function get (url, params = {}) {
  return new Promise((resolve, reject) => {
    axios
      .get(url, {
        params: params
      })
      .then(response => {
        if (response.success) {
          resolve(response.data)
        }
      })
      .catch(err => {
        reject(err)
      })
  })
}

/**
 * 封裝post請求
 * @param url
 * @param data
 * @returns {Promise}
 */
export function post (url, data = {}) {
  return new Promise((resolve, reject) => {
    axios.post(url, data).then(
      response => {
        if (response.success) {
          resolve(response.data)
        }
      },
      err => {
        reject(err)
      }
    )
  })
}
複製程式碼
  1. 重點:新建 api.js 檔案 將後臺請求介面全部寫在此處,統一管理
import { get, post } from './axios'
const api = {
     reqLogin: p => post('api/user/addFormId', p),
      reqGetInfo: p => post('api/user/addFormId', p)
}
export default api

// 將 api 引入到 main.js 中
Vue.prototype.$api = api

// 這樣頁面中使用
this.$api.reqLogin().then(res => {
      console.log(res)
})
複製程式碼

是不是非常方便?鼓掌 啪啪啪啪......

web 前端群招人,有夢想的一群小青年 www.jianshu.com/p/33eee1c26…

相關文章