【轉】手摸手,帶你用vue擼后台 系列一


前言

說好的教程終於來了,第一篇文章主要來說一說在開始寫業務代碼前的一些准備工作吧,但這里不會教你webpack的基礎配置,熱更新怎么做,webpack速度優化等等,有需求的請自行google。

目錄結構

├── build                      // 構建相關 ├── config // 配置相關 ├── src // 源代碼 │ ├── api // 所有請求 │ ├── assets // 主題 字體等靜態資源 │ ├── components // 全局公用組件 │ ├── directive // 全局指令 │ ├── filtres // 全局filter │ ├── mock // mock數據 │ ├── router // 路由 │ ├── store // 全局store管理 │ ├── styles // 全局樣式 │ ├── utils // 全局公用方法 │ ├── view // view │ ├── App.vue // 入口頁面 │ └── main.js // 入口 加載組件 初始化等 ├── static // 第三方不打包資源 │ ├── jquery │ └── Tinymce // 富文本 ├── .babelrc // babel-loader 配置 ├── eslintrc.js // eslint 配置項 ├── .gitignore // git 忽略項 ├── favicon.ico // favicon圖標 ├── index.html // html模板 └── package.json // package.json

這里來簡單講一下src文件

api 和 views

簡單截取一下公司后台項目,現在后台大概有三十多個api模塊


Paste_Image.png


如圖可見,模塊是很多的,而且隨着業務的迭代,模塊會越來越多。
所以這里建議根據業務模塊來划分views,並且將views 和 api 兩個模塊一一對應,方便維護.如下圖


Paste_Image.png

如article模塊下放的都是文章相關的api,這樣不管項目怎么累加,api和viede的維護還是清晰的,當然也有一些全區公用的api模塊,如七牛upload,remoteSearch等等,這些單獨放置就行。

components

這里的components放置的都是全局公用的一些組件,如上傳組件,富文本等等。一些頁面級的組件建議還是放在各自views文件下,如圖


Paste_Image.png

store

這里我個人建議不要為了用vuex而用vuex。就拿我司的后台項目來說,它雖然比較龐大,二三十個業務模塊,十幾種權限,但業務之間的耦合度是很低的,文章模塊和評論模塊幾乎是倆個獨立的東西,所以根本沒有必要使用vuex來存儲data,每個頁面里存放自己的data就行。當然有些數據還是需要用vuex來統一管理的,如登錄token,用戶信息,或者是一些全局個人偏好設置等,還是用vuex管理更加的方便,具體當然還是要結合自己的業務場景的。總之還是那句話,不要為了用vuex而用vuex!


webpack

這里是用vue-cli為基礎模板構建的,如果你對這個有什么疑惑請自行google,相關的配置介紹文章已經很詳細了,這里就不再展開了。簡單說一說需要注意到地方。

jquery

管理后台不同於前台項目,會經常用到一些第三方插件,但有些插件是不得不依賴jquery的,如市面上好的富文本基都是依賴jquery的,所以干脆就直接引入到項目中省事(gzip之后只有34kb,而且常年from cache,不要考慮那些吹毛求疵的大小問題,這幾kb和提高的開發效率根本不能比)。但是如果第三方庫的代碼中出現$.xxx或jQuery.xxx或window.jQuery或window.$則會直接報錯。要達到類似的效果,則需要使用webpack內置的ProvidePlugin插件,配置很簡單,只需要

     new webpack.ProvidePlugin({ $: 'jquery' , 'jQuery': 'jquery' })

這樣當webpack碰到require的第三方庫中出現全局的$、jQeury和window.jQuery時,就會使用node_module下jquery包export出來的東西了。

alias

當項目逐漸變大之后,文件與文件直接的引用關系會很復雜,這時候就需要使用alias了。
有的人喜歡alias 指向src目錄下,再使用相對路徑找文件

resolve: {
    alias: { '~': resolve(__dirname, 'src') } } //使用 import stickTop from '~/components/stickTop'

我習慣於

alias: {
  'src': path.resolve(__dirname, '../src'), 'components': path.resolve(__dirname, '../src/components'), 'api': path.resolve(__dirname, '../src/api'), 'utils': path.resolve(__dirname, '../src/utils'), 'store': path.resolve(__dirname, '../src/store'), 'router': path.resolve(__dirname, '../src/router') } //使用 import stickTop from 'components/stickTop' import getArticle from 'api/article'

沒有好與壞對與錯,純看個人喜好和團隊規范。


eslint

不管是多人合作還是個人項目,代碼規范是很重要的。這樣做不僅可以很大程度地避免基本語法錯誤,也保證了代碼的可讀性。這所謂工欲善其事,必先利其器,個人推薦eslint+vscode來寫vue,絕對有種飛一般的感覺。效果如圖:


eslintGif.gif


每次保存,vscode就能標紅不符合eslint規則的地方,同時還會做一些簡單的自我修正。安裝步驟如下:

首先安裝eslint插件


eslint1.png

安裝並配置完成 ESLint 后,我們繼續回到 VSCode 進行擴展設置,依次點擊 文件 > 首選項 > 設置 打開 VSCode 配置文件,添加如下配置

    "files.autoSave":"off", "eslint.validate": [ "javascript", "javascriptreact", "html", { "language": "vue", "autoFix": true } ], "eslint.options": { "plugins": ["html"] }

這樣每次保存的時候就可以根據根目錄下.eslintrc.js你配置的eslint規則來檢查和做一些簡單的fix。這里提供了一份我平時的eslint規則地址,都簡單寫上了注釋。每個人和團隊都有自己的代碼規范,統一就好了,去打造一份屬於自己的eslint 規則上傳到npm吧,如餓了么團隊的config,vue的config


封裝axios

我們經常遇到一些線上的bug,但測試環境很難模擬。其實可以通過簡單的配置就可以在本地調試線上環境。
這里結合業務封裝了axios ,線上代碼

import axios from 'axios'; import { Message } from 'element-ui'; import store from '../store'; import router from '../router'; export default function _fetch(options) { return new Promise((resolve, reject) => { const instance = axios.create({ baseURL: process.env.BASE_API, //通過env環境變量切換api地址 // timeout: 2000, //請求超時時間 headers: { 'X-Token': store.getters.token }//后台項目,每個請求都需要token,判斷權限 }); instance(options) .then(response => { const res = response.data; //我司通過自定義code來判斷 如:code不等於20000就被試為異常 if (res.code !== 20000) { console.log(options); // for debug Message({ message: res.message, type: 'error', duration: 5 * 1000 }); // 50014:Token 過期了 50012:其他客戶端登錄了 50008:非法的token if (res.code === 50008 || res.code === 50014 || res.code === 50012) { Message({ message: res.message, type: 'error', duration: 5 * 1000 }); // 登出 store.dispatch('FedLogOut').then(() => { router.push({ path: '/login' }) }); } reject(res); } resolve(res); }) .catch(error => { Message({ message: '發生異常錯誤,請刷新頁面重試,或聯系程序員', type: 'error', duration: 5 * 1000 }); console.log(error); // for debug reject(error); }); }); }
//使用 export function getInfo(token) { return _fetch({ url: '/user/info', method: 'get', params: { token } }); }

比如后台項目,每一個請求都是要帶token來驗證權限的,這樣封裝以下的話我們就不用每個請求都手動來塞token,或者來做異常處理,一勞永逸。
而且因為我們的api是更具env環境變量動態切換的,如果以后線上出現了bug,我們只要將配置dev.env.js

module.exports = {
    NODE_ENV: '"development"', BASE_API: '"https://api-dev"', //修改為'"https://api-prod"'就行了 APP_ORIGIN: '"https://wallstreetcn.com"' //為公司打個廣告 pc站為vue+ssr }

媽媽再也不用擔心我調試線上bug了。
當然這里只是簡單舉了個例子,axios還可以執行多個並發請求,攔截器什么的,大家自行去研究吧。


多環境

vue-cli 默認只提供了dev和prod兩種環境。但其實正真的開發流程可能還會多一個sit環境,就是所謂的測試環境。所以我們就要簡單的修改一下代碼。其實很簡單就是設置不同的環境變量

"build:prod": "NODE_ENV=production node build/build.js", "build:sit": "NODE_ENV=sit node build/build.js",

之后在代碼里自行判斷,想干就干啥

var env = process.env.NODE_ENV === 'production' ? config.build.prodEnv : config.build.sitEnv

新版的vue-cli也內置了webpack-bundle-analyzer 一個模塊分析的東西,相當的好用。使用方法也很簡單,和之前一樣封裝一個npm script 就可以。

//package.json "build:sit-preview": "NODE_ENV=sit npm_config_preview=true npm_config_report=true node build/build.js" //之后通過process.env.npm_config_report來判斷是否來啟用webpack-bundle-analyzer var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin webpackConfig.plugins.push(new BundleAnalyzerPlugin())

效果圖


analyzer.png


webpack-bundle-analyzer這個插件還是很有用的,對后期的代碼優化什么的,最重要的是它夠裝逼~


前后端交互

每個公司都有自己一套的開發流程,沒有絕對的好與壞。這里我來講講我司的前后端開發流程。

跨域問題

首先前后端交互不可避免的就會遇到跨域問題,我司現在全是用cors來解決的,如果你司后端嫌麻煩不肯配置的話,dev環境也可以通過
webpack-dev-server的proxy來解決,開發環境用nginx反代理一下就好了,具體配置這里就不展開了。

前后端的交流問題

其實大家也知道,平時的開發中交流成本占據了我們很大一部分時間,但前后端如果有一個好的協作方式的話能解決很多時間。我司開發流程都是前后端和產品討論項目,之后 后端mock api 生成好文檔,我們前端才是對接接口的。這里推薦一個文檔生成器swagger
swagger是一個REST APIs文檔生成工具,可以在許多不同的平台上從代碼注釋中自動生成,開源,支持大部分語言,社區好,總之就是一個神奇,給大家透露一下我司的api 文檔(swagger自動生成,ui忽略)


Paste_Image.png


url地址,需要傳是沒參數,需要的傳參類型,返回的數據格式什么都一清二楚了,我們大前端終於不用再看后端的臉色了~

前端自行mock

如果后端不肯來幫你mock數據的話,前端自己來mock也是很簡單的。你可以使用mock server 或者使用mockjs+rap也是很方便的。


iconfont

element-ui 默認的icon不是很多,這里要安利一波阿里的iconfont簡直是神器,不管是公司項目還是個人項目都在使用。它提供了png,ai,svg三種格式,同時使用也支持unicode,font-class,symbol三種方式。由於是管理后台對兼容性要求不高,樓主平時都喜歡用symbol,就是用svg的方式引入iconfont.js,之后就能歡快的去選icon了,還能自己上傳icon。曬一波我司后台的圖標(都是樓主自己發揮的)。


iconfont.png

router-view

different router the same component vue。真實的業務場景中,這種情況很多。比如


router-view.png


我創建和編輯的頁面使用的是同一個component,默認情況下當這兩個頁面切換時並不會觸發vue的created或者mounted鈎子,官方說你可以通過watch $route的變化來做處理,但其實說真的還是蠻麻煩的。后來發現其實可以簡單的在 router-view上加上一個唯一的key,來保證路由切換時都會重新渲染觸發鈎子了。這樣簡單的多了。

<router-view :key="key"></router-view> computed: { key() { return this.$route.name !== undefined? this.$route.name + +new Date(): this.$route + +new Date() } }

優化

有些人會覺得現在構建是不是有點慢,我司現在技術棧是容器服務,后台項目會把dist文件夾里的東西都會打包成一個docker鏡像,基本步驟為

npm install
npm run build:prod 加打包鏡像,一共是耗時如下

Paste_Image.png

還是屬於能接受時間的范圍。
主站PC站基於nodejs、Vue實現服務端渲染,所以不僅需要依賴nodejs,而且需要利用pm2進行nodejs生命周期的管理。為了加速線上鏡像構建的速度,我們利用taobao源 https://registry.npm.taobao.org 進行加速, 並且將一些常見的npm依賴打入了基礎鏡像,避免每次都需要重新下載。
這里注意下 建議不要使用cnpm install或者update 它的包都是一個link,反正會有各種詭異的bug,這里建議這樣使用

npm install --registry=https://registry.npm.taobao.org

如果你覺得慢還是有可優化的空間如使用webpack dll 或者把那些第三方vendor單獨打包 external出去,或者我司現在用的是http2 可以使用AggressiveSplittingPlugin等等,這里有需求的可以自行優化。


占坑

常規占坑,這里是手摸手,帶你用vue擼后台 系列一,下一篇會主要講講搭建用戶系統,二次登錄,權限驗證這些東西,有時間的話,還會寫一下基於element-ui動態換膚的實現方案。或者大家可以留言說說想要看一些什么。



作者:花褲衩coder
鏈接:http://www.jianshu.com/p/c315c9211146
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM