手摸手,带你用vue撸后台 系列一(基础篇) - 掘金
完整項目地址:vue-element-admin
系列文章:
- 手摸手,帶你用 vue 擼后臺 系列一(基礎(chǔ)篇)
- 手摸手,帶你用 vue 擼后臺 系列二(登錄權(quán)限篇)
- 手摸手,帶你用 vue 擼后臺 系列三 (實戰(zhàn)篇)
- 手摸手,帶你用 vue 擼后臺 系列四(vueAdmin 一個極簡的后臺基礎(chǔ)模板)
- 手摸手,帶你用 vue 擼后臺 系列五(v4.0 新版本)
- 手摸手,帶你封裝一個 vue component
- 手摸手,帶你優(yōu)雅的使用 icon
- 手摸手,帶你用合理的姿勢使用 webpack4(上)
- 手摸手,帶你用合理的姿勢使用 webpack4(下)
前言
說好的教程終于來了,第一篇文章主要來說一說在開始寫實際業(yè)務(wù)代碼之前的一些準(zhǔn)備工作吧,但這里不會教你 webpack 的基礎(chǔ)配置,熱更新原理是什么,webpack速度優(yōu)化等等,有需求的請自行 google,相關(guān)文章已經(jīng)很多了。
目錄結(jié)構(gòu)
├── build // 構(gòu)建相關(guān)?? ├── config // 配置相關(guān) ├── src // 源代碼 │?? ├── api // 所有請求 │?? ├── assets // 主題 字體等靜態(tài)資源 │?? ├── components // 全局公用組件 │?? ├── directive // 全局指令 │?? ├── filtres // 全局 filter │?? ├── icons // 項目所有 svg icons │?? ├── lang // 國際化 language │?? ├── mock // 項目mock 模擬數(shù)據(jù) │?? ├── router // 路由 │?? ├── store // 全局 store管理 │?? ├── styles // 全局樣式 │?? ├── utils // 全局公用方法 │?? ├── vendor // 公用vendor │?? ├── views // view │?? ├── App.vue // 入口頁面 │?? ├── main.js // 入口 加載組件 初始化等 │ └── permission.js // 權(quán)限管理 ├── static // 第三方不打包資源 │?? └── Tinymce // 富文本 ├── .babelrc // babel-loader 配置 ├── eslintrc.js // eslint 配置項 ├── .gitignore // git 忽略項 ├── favicon.ico // favicon圖標(biāo) ├── index.html // html模板 └── package.json // package.json 復(fù)制代碼這里來簡單講一下src文件
api 和 views
簡單截取一下公司后臺項目,現(xiàn)在后臺大概有四五十個 api 模塊
?
如圖可見模塊有很多,而且隨著業(yè)務(wù)的迭代,模塊還會會越來越多。 所以這里建議根據(jù)業(yè)務(wù)模塊來劃分 views,并且 將views 和 api 兩個模塊一一對應(yīng),從而方便維護(hù)。如下圖:
?
?
如 article 模塊下放的都是文章相關(guān)的 api,這樣不管項目怎么累加,api和views的維護(hù)還是清晰的,當(dāng)然也有一些全區(qū)公用的api模塊,如七牛upload,remoteSearch等等,這些單獨放置就行。
components
這里的 components 放置的都是全局公用的一些組件,如上傳組件,富文本等等。一些頁面級的組件建議還是放在各自views文件下,方便管理。如圖:
?
?
store
這里我個人建議不要為了用 vuex 而用 vuex。就拿我司的后臺項目來說,它雖然比較龐大,幾十個業(yè)務(wù)模塊,幾十種權(quán)限,但業(yè)務(wù)之間的耦合度是很低的,文章模塊和評論模塊幾乎是倆個獨立的東西,所以根本沒有必要使用 vuex 來存儲data,每個頁面里存放自己的 data 就行。當(dāng)然有些數(shù)據(jù)還是需要用 vuex 來統(tǒng)一管理的,如登錄token,用戶信息,或者是一些全局個人偏好設(shè)置等,還是用vuex管理更加的方便,具體當(dāng)然還是要結(jié)合自己的業(yè)務(wù)場景的。總之還是那句話,不要為了用vuex而用vuex!
webpack
這里是用 vue-cli 的 webpack-template 為基礎(chǔ)模板構(gòu)建的,如果你對這個有什么疑惑請自行g(shù)oogle,相關(guān)的配置紹其它的文章已經(jīng)介詳細(xì)了,這里就不再展開了。簡單說一些需要注意到地方。
jquery (本項目已移除)
管理后臺不同于前臺項目,會經(jīng)常用到一些第三方插件,但有些插件是不得不依賴 jquery 的,如市面很多富文本基都是依賴 jquery 的,所以干脆就直接引入到項目中省事(gzip之后只有34kb,而且常年from cache,不要考慮那些吹毛求疵的大小問題,這幾kb和提高的開發(fā)效率根本不能比)。但是如果第三方庫的代碼中出現(xiàn)?則會直接報錯。要達(dá)到類似的效果,則需要使用 webpack 內(nèi)置的 ProvidePlugin 插件,配置很簡單,只需要
new webpack.ProvidePlugin({$: 'jquery' ,'jQuery': 'jquery' }) 復(fù)制代碼這樣當(dāng) webpack 碰到 require 的第三方庫中出現(xiàn)全局的$、jQeury和window.jQuery 時,就會使用 node_module 下 jquery 包 export 出來的東西了。
alias
當(dāng)項目逐漸變大之后,文件與文件直接的引用關(guān)系會很復(fù)雜,這時候就需要使用alias 了。 有的人喜歡alias 指向src目錄下,再使用相對路徑找文件
resolve: {alias: {'~': resolve(__dirname, 'src')} }//使用 import stickTop from '~/components/stickTop' 復(fù)制代碼或者也可以
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' 復(fù)制代碼沒有好與壞對與錯,純看個人喜好和團(tuán)隊規(guī)范。
ESLint
不管是多人合作還是個人項目,代碼規(guī)范是很重要的。這樣做不僅可以很大程度地避免基本語法錯誤,也保證了代碼的可讀性。這所謂工欲善其事,必先利其器,個人推薦 eslint+vscode 來寫 vue,絕對有種飛一般的感覺。效果如圖:
?
每次保存,vscode就能標(biāo)紅不符合eslint規(guī)則的地方,同時還會做一些簡單的自我修正。安裝步驟如下:
?
首先安裝eslint插件
?
?
安裝并配置完成 ESLint 后,我們繼續(xù)回到 VSCode 進(jìn)行擴(kuò)展設(shè)置,依次點擊 文件 > 首選項 > 設(shè)置 打開 VSCode 配置文件,添加如下配置
"files.autoSave":"off","eslint.validate": ["javascript","javascriptreact","html",{?"language":?"vue",?"autoFix":?true?}],"eslint.options": {"plugins": ["html"]}復(fù)制代碼這樣每次保存的時候就可以根據(jù)根目錄下.eslintrc.js你配置的eslint規(guī)則來檢查和做一些簡單的fix。這里提供了一份我平時的eslint規(guī)則地址,都簡單寫上了注釋。每個人和團(tuán)隊都有自己的代碼規(guī)范,統(tǒng)一就好了,去打造一份屬于自己的eslint 規(guī)則上傳到npm吧,如餓了么團(tuán)隊的 config,vue的 config。
vscode 插件和配置推薦
封裝 axios
我們經(jīng)常遇到一些線上 的bug,但測試環(huán)境很難模擬。其實可以通過簡單的配置就可以在本地調(diào)試線上環(huán)境。 這里結(jié)合業(yè)務(wù)封裝了axios ,線上代碼
import axios from 'axios' import { Message } from 'element-ui' import store from '@/store' import { getToken } from '@/utils/auth'// 創(chuàng)建axios實例 const service = axios.create({baseURL: process.env.BASE_API, // api的base_urltimeout: 5000 // 請求超時時間 })// request攔截器 service.interceptors.request.use(config => {// Do something before request is sentif (store.getters.token) {config.headers['X-Token'] = getToken() // 讓每個請求攜帶token--['X-Token']為自定義key 請根據(jù)實際情況自行修改}return config }, error => {// Do something with request errorconsole.log(error) // for debugPromise.reject(error) })// respone攔截器 service.interceptors.response.use(response => response,/*** 下面的注釋為通過response自定義code來標(biāo)示請求狀態(tài),當(dāng)code返回如下情況為權(quán)限有問題,登出并返回到登錄頁* 如通過xmlhttprequest 狀態(tài)碼標(biāo)識 邏輯可寫在下面error中*/// const res = response.data;// if (res.code !== 20000) {// Message({// message: res.message,// type: 'error',// duration: 5 * 1000// });// // 50008:非法的token; 50012:其他客戶端登錄了; 50014:Token 過期了;// if (res.code === 50008 || res.code === 50012 || res.code === 50014) {// MessageBox.confirm('你已被登出,可以取消繼續(xù)留在該頁面,或者重新登錄', '確定登出', {// confirmButtonText: '重新登錄',// cancelButtonText: '取消',// type: 'warning'// }).then(() => {// store.dispatch('FedLogOut').then(() => {// location.reload();// 為了重新實例化vue-router對象 避免bug// });// })// }// return Promise.reject('error');// } else {// return response.data;// }error => {console.log('err' + error)// for debugMessage({message: error.message,type: 'error',duration: 5 * 1000})return Promise.reject(error)})export default service復(fù)制代碼 import request from '@/utils/request'//使用 export function getInfo(params) {return request({url: '/user/info',method: 'get',params}); } 復(fù)制代碼比如后臺項目,每一個請求都是要帶 token 來驗證權(quán)限的,這樣封裝以下的話我們就不用每個請求都手動來塞 token,或者來做一些統(tǒng)一的異常處理,一勞永逸。 而且因為我們的 api 是根據(jù) env 環(huán)境變量動態(tài)切換的,如果以后線上出現(xiàn)了bug,我們只需配置一下 @/config/dev.env.js 再重啟一下服務(wù),就能在本地模擬線上的環(huán)境了。
module.exports = {NODE_ENV: '"development"',BASE_API: '"https://api-dev"', //修改為'"https://api-prod"'就行了APP_ORIGIN: '"https://wallstreetcn.com"' //為公司打個廣告 pc站為vue+ssr }復(fù)制代碼媽媽再也不用擔(dān)心我調(diào)試線上bug了。 當(dāng)然這里只是簡單舉了個例子,axios還可以執(zhí)行多個并發(fā)請求,攔截器什么的,大家自行去研究吧。
多環(huán)境
vue-cli 默認(rèn)只提供了dev和prod兩種環(huán)境。但其實正真的開發(fā)流程可能還會多一個sit或者stage環(huán)境,就是所謂的測試環(huán)境和預(yù)發(fā)布環(huán)境。所以我們就要簡單的修改一下代碼。其實很簡單就是設(shè)置不同的環(huán)境變量
"build:prod": "NODE_ENV=production node build/build.js", "build:sit": "NODE_ENV=sit node build/build.js", 復(fù)制代碼之后在代碼里自行判斷,想干就干啥
var env = process.env.NODE_ENV === 'production' ? config.build.prodEnv : config.build.sitEnv 復(fù)制代碼新版的 vue-cli 也內(nèi)置了 webpack-bundle-analyzer 一個模塊分析的東西,相當(dāng)?shù)暮糜谩J褂梅椒ㄒ埠芎唵?#xff0c;和之前一樣封裝一個 npm script 就可以。
//package.json"build:sit-preview": "cross-env NODE_ENV=production env_config=sit npm_config_preview=true npm_config_report=true node build/build.js"//之后通過process.env.npm_config_report來判斷是否來啟用webpack-bundle-analyzervar BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 復(fù)制代碼效果圖
?
webpack-bundle-analyzer這個插件還是很有用的,對后期的代碼優(yōu)化什么的,最重要的是它夠裝逼~
?
前后端交互
每個公司都有自己一套的開發(fā)流程,沒有絕對的好與壞。這里我來講講我司的前后端交互流程。
跨域問題
首先前后端交互不可避免的就會遇到跨域問題,我司現(xiàn)在全是用 cors來解決的,如果你司后端嫌麻煩不肯配置的話,dev環(huán)境也可以通過 webpack-dev-server的proxy來解決,開發(fā)環(huán)境用nginx反代理一下就好了,具體配置這里就不展開了。
前后端的交互問題
其實大家也知道,平時的開發(fā)中交流成本占據(jù)了我們很大一部分時間,但前后端如果有一個好的協(xié)作方式的話能解決很多時間。我司開發(fā)流程都是前后端和產(chǎn)品一起開會討論項目,之后后端根據(jù)需求,首先定義數(shù)據(jù)格式和api,然后 mock api 生成好文檔,我們前端才是對接接口的。這里推薦一個文檔生成器 swagger。 swagger是一個REST APIs文檔生成工具,可以在許多不同的平臺上從代碼注釋中自動生成,開源,支持大部分語言,社區(qū)好,總之就是一個強(qiáng)大,如下圖的api 文檔(swagger自動生成,ui忽略)
?
?
api 地址,需要傳是沒參數(shù),需要的傳參類型,返回的數(shù)據(jù)格式什么都一清二楚了。
?
前端自行mock
如果后端不肯來幫你 mock 數(shù)據(jù)的話,前端自己來 mock 也是很簡單的。你可以使用mock server 或者使用 mockjs + rap 也是很方便的。 不久前出的 easy-mock也相當(dāng)?shù)牟诲e,還能結(jié)合 swagger。 我們大前端終于不用再看后端的臉色了~
iconfont
element-ui 默認(rèn)的icon不是很多,這里要安利一波阿里的iconfont簡直是神器,不管是公司項目還是個人項目都在使用。它提供了png,ai,svg三種格式,同時使用也支持unicode,font-class,symbol三種方式。由于是管理后臺對兼容性要求不高,樓主平時都喜歡用symbol,曬一波我司后臺的圖標(biāo)(都是樓主自己發(fā)揮的)。
?
詳細(xì)具體的使用可以見文章 手摸手,帶你優(yōu)雅的使用 icon
?
router-view
different router the same component vue。真實的業(yè)務(wù)場景中,這種情況很多。比如
?
我創(chuàng)建和編輯的頁面使用的是同一個component,默認(rèn)情況下當(dāng)這兩個頁面切換時并不會觸發(fā)vue的created或者mounted鉤子,官方說你可以通過watch $route的變化來做處理,但其實說真的還是蠻麻煩的。后來發(fā)現(xiàn)其實可以簡單的在 router-view上加上一個唯一的key,來保證路由切換時都會重新渲染觸發(fā)鉤子了。這樣簡單的多了。
?
<router-view :key="key"></router-view>computed: {key() {return this.$route.name !== undefined? this.$route.name + +new Date(): this.$route + +new Date()}} 復(fù)制代碼優(yōu)化
有些人會覺得現(xiàn)在構(gòu)建是不是有點慢,我司現(xiàn)在技術(shù)棧是容器服務(wù),后臺項目會把dist文件夾里的東西都會打包成一個docker鏡像,基本步驟為
npm install npm run build:prod 加打包鏡像,一共是耗時如下 復(fù)制代碼?
?
?
還是屬于能接受時間的范圍。 主站PC站基于nodejs、Vue實現(xiàn)服務(wù)端渲染,所以不僅需要依賴nodejs,而且需要利用pm2進(jìn)行nodejs生命周期的管理。為了加速線上鏡像構(gòu)建的速度,我們利用taobao源 registry.npm.taobao.org 進(jìn)行加速, 并且將一些常見的npm依賴打入了基礎(chǔ)鏡像,避免每次都需要重新下載。 這里注意下 建議不要使用cnpm install或者update 它的包都是一個link,反正會有各種詭異的bug,這里建議這樣使用
npm install --registry=https://registry.npm.taobao.org 復(fù)制代碼如果你覺得慢還是有可優(yōu)化的空間如使用webpack dll 或者把那些第三方vendor單獨打包 external出去,或者我司現(xiàn)在用的是http2 可以使用AggressiveSplittingPlugin等等,這里有需求的可以自行優(yōu)化。
占坑
常規(guī)占坑,這里是手摸手,帶你用vue擼后臺系列。 完整項目地址:vue-element-admin
-
手摸手,帶你用 vue 擼后臺 系列一(基礎(chǔ)篇)
-
手摸手,帶你用 vue 擼后臺 系列二(登錄權(quán)限篇)
-
手摸手,帶你用 vue 擼后臺 系列三 (實戰(zhàn)篇)
-
手摸手,帶你用 vue 擼后臺 系列四(vueAdmin 一個極簡的后臺基礎(chǔ)模板)
-
手摸手,帶你用 vue 擼后臺 系列五(v4.0 新版本)
-
手摸手,帶你封裝一個 vue component
-
手摸手,帶你優(yōu)雅的使用 icon
-
手摸手,帶你用合理的姿勢使用 webpack4(上)
-
手摸手,帶你用合理的姿勢使用 webpack4(下)
作者:花褲衩
鏈接:https://juejin.im/post/6844903476661583880
來源:掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
總結(jié)
以上是生活随笔為你收集整理的手摸手,带你用vue撸后台 系列一(基础篇) - 掘金的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux命令unzip,linux u
- 下一篇: 第一、二章 引论、算法分析