總結(jié)我對(duì)Vue項(xiàng)目團(tuán)隊(duì)開發(fā)的一些基本配置封裝分享
本文已獲得原作者的獨(dú)家授權(quán),有想轉(zhuǎn)載的朋友們可以在后臺(tái)聯(lián)系我申請(qǐng)開白哦! PS:歡迎掘友們向我投稿哦,被采用的文章還可以送你掘金精美周邊!
本文已授權(quán)掘金開發(fā)者社區(qū)公眾號(hào)獨(dú)家使用,包括但不限于編輯、標(biāo)注原創(chuàng)等權(quán)益
簡介
本篇文章主要帶來的是 vue 基礎(chǔ)架構(gòu)?篇,大家都知道, Vue3.0?后 Vue2.0?會(huì)有一個(gè)終結(jié)版出來,也就說明 Vue?迎來了新時(shí)代,但是并不是所有項(xiàng)目都能夠一起邁向新時(shí)代的輪船。本文主要是承接上篇優(yōu)化的技巧文章做一個(gè)續(xù)篇吧,這個(gè)續(xù)篇主要是針對(duì)團(tuán)隊(duì)開發(fā)相關(guān)的東西,相關(guān)插件和庫只是微微帶過,如果本文能夠推動(dòng)你們的生產(chǎn)線,就點(diǎn)個(gè)贊吧。
配置相關(guān)類的可以去搜索對(duì)應(yīng)的分享貼,或者看我之前的文章,本文內(nèi)容較為貼合團(tuán)隊(duì)開發(fā),非工具鏈分享文,大部分都能引發(fā)一些技術(shù)層面的思考。
前言
在很多時(shí)候,對(duì)于 vue?項(xiàng)目來說,很多剛?cè)腴T,或者是受業(yè)務(wù)妥協(xié)的朋友大都是從百度 CV?一套看得過去的架子,如常見的 D2Admin?, vue-element-admin?,進(jìn)行一個(gè)二次迭代的開發(fā),其項(xiàng)目本身非常的優(yōu)質(zhì),而在其 template?中去進(jìn)行一個(gè)更改能夠使得項(xiàng)目在一開始有一個(gè)很好的基礎(chǔ)環(huán)境,但是如果沒有花時(shí)間去琢磨透其中三分明細(xì)。在后續(xù)排雷來說,無疑是非常的困難的,因此大部分前端團(tuán)隊(duì)都會(huì)重構(gòu)出自己的一套基礎(chǔ)腳手架封裝,有通過 webpack進(jìn)行處理的,也有基于 VueCli?打造的,最終都是自身團(tuán)隊(duì)的財(cái)產(chǎn),從技術(shù)分享都細(xì)分實(shí)踐都能給團(tuán)隊(duì)的小伙伴或多或少帶來一些開發(fā)上面的便利。對(duì)后續(xù)團(tuán)隊(duì)人員的變動(dòng)也能快速的投入生產(chǎn)當(dāng)中。
做了什么?
基本 HTTP 請(qǐng)求封裝 約定式 HTTP 請(qǐng)求管理 Mmixin 數(shù)據(jù)管理 jsdoc 項(xiàng)目文檔 log 異常處理 組件和頁面管理 常用的指令 使用 sass 還是 scss? @mixin 和 %placeholder eslint
基本 HTTP 請(qǐng)求做了什么?
錯(cuò)誤處理
在這里選用的是現(xiàn)如今兼容性比較好的 axios?,可以說是比較好的一個(gè)請(qǐng)求庫,相比于 fetch?來說,兩者各有優(yōu)勢(shì),(我已經(jīng)開始使用 fetch?)。這一部分其實(shí)無非就是封裝一些公共調(diào)用時(shí)需要處理的行為,如:token?, 請(qǐng)求攔截?, 響應(yīng)攔截?, 錯(cuò)誤碼約定?, 異常上報(bào)?, 中間件?等一系列基礎(chǔ)的行為模式。
如下實(shí)例,當(dāng) HTTP?請(qǐng)求出現(xiàn)錯(cuò)誤的時(shí)候,首先通過 getEnv?獲取當(dāng)前的開發(fā)環(huán)境,如果是 dev(開發(fā)環(huán)境下)?只做一個(gè)簡單的 console.log,非開發(fā)環(huán)境下,則是上報(bào)進(jìn)行異常監(jiān)聽,對(duì)于前后端來說都
function?handleError?(?error,?msg)?{
??if?(getEnv()?===?'dev')?{
????tools.log.danger('>>>>>>?HTTP?Error?>>>>>>')
????console.log(error,?msg)
??}?else?{
????Store.dispatch('logs/push',?{
??????message:?msg,
??????type:?'danger'
????})
??}
}
RESTFul
相對(duì)于一些攔截器來說,都非常的簡單,需要注意的無非就是根據(jù)團(tuán)隊(duì)的一些規(guī)范制定一些規(guī)則,如常見的 code?碼等方法,大部分情況下,如無意外,99% 的接口都是請(qǐng)求成功的,但因?yàn)樘厥庑?,?nèi)部會(huì)有一個(gè) code?的狀態(tài)來定義正反向。同樣的,在操作接口時(shí),一些狀態(tài)也是需要和接口的請(qǐng)求方式同步,參考如下:
GET: 200 OK POST: 201 Created PUT: 200 OK DELETE: 204 No Content
現(xiàn)如今大部分的接口的規(guī)范都使用 RESTful?,如果不知道 RESTful?是什么,可以看看 @阮一峰?的文章來初步了解。RESTful API 最佳實(shí)踐 @阮一峰的網(wǎng)絡(luò)日志
狀態(tài)碼機(jī)制
同樣的 code?中我們也自定義日常開發(fā)中的一些狀態(tài)碼,當(dāng)我們需要用到 第三方API?的時(shí)候,前后端都需要快速的定位是自身服務(wù)的問題,還是其他服務(wù)(例如中臺(tái))的問題,因此對(duì)接服務(wù)我們都自定義了一些 code?來陳述這一類錯(cuò)誤的處理??梢詤⒖既缦拢@些其實(shí)都是創(chuàng)建在一個(gè)對(duì)象當(dāng)中的:
自定義 code
| code | 狀態(tài) | 描述 |
|---|---|---|
| 30000 | invalid credential | 不合法的憑證 |
| 30001 | invalid connect_type | 不合法的 connect_type |
| 30001 | invalid group_conf_id | 不合法的 group_conf_id |
| ...... | ...... | ...... |
當(dāng)我們細(xì)化一些異常時(shí),這時(shí)候是可以劃分的非常細(xì)致的,這里給出微信的一些參考:
| 40039 | invalid url size | 不合法的 url 長度 |
|---|---|---|
| 40048 | invalid url domain | 不合法的 url 域名 |
| 40054 | invalid sub button url domain | 不合法的子菜單按鈕 url 域名 |
| 40055 | invalid button url domain | 不合法的菜單按鈕 url 域名 |
| 40066 | invalid url | 不合法的 url |
| 41001 | access_token missing | 缺失 access_token 參數(shù) |
| 41002 | appid missing | 缺失 appid 參數(shù) |
| 41003 | refresh_token missing | 缺失 refresh_token 參數(shù) |
| 41004 | appsecret missing | 缺失 secret 參數(shù) |
| 41005 | media data missing | 缺失二進(jìn)制媒體文件 |
| 41006 | media_id missing | 缺失 media_id 參數(shù) |
| 41007 | sub_menu data missing | 缺失子菜單數(shù)據(jù) |
| 41008 | missing code | 缺失 code 參數(shù) |
| 41009 | missing openid | 缺失 openid 參數(shù) |
| 41010 | missing url | 缺失 url 參數(shù) |
| 42001 | access_token expired | access_token 超時(shí) |
| 42002 | refresh_token expired | refresh_token 超時(shí) |
function?createHttpService?(settings)?{
??const?service?=?Axios.create(settings)
??service.interceptors.request.use(
????config?=>?{
??????
??????const?token?=?localStorage.getItem('access_token')
??????config.headers.token?=?token
??????return?config
????},
????error?=>?{
??????return?Promise.reject(error)
????}
??)
??
??service.interceptors.response.use(
????response?=>?{
??????console.log(response)
??????const?{?code,?message,?data?}?=?response.data
??????
??????if?(code?>=?30000)?{
????????console.log('>>>?自定義錯(cuò)誤信息,全局提示處理',?message)
????????return?data
??????}
??????
??????if?(code?>=?200?&&?code?300)?{
????????return?data
??????}
??????
??????if?(code?>=?300?&&?code?600)?{
????????return?Promise.reject(response.data)
??????}
????},
????error?=>?{
??????const?{?status?=?404?}?=?error?.response
??????if?(Object.prototype.hasOwnProperty.call(codeMessage,?status))?{
????????handleError(error,?codeMessage[status])
??????}
??????throw?error
????}
??)
??return?service
}
const?http?=?createHttpService({
??withCredentials,
??timeout,
??baseURL
})
約定式 http 請(qǐng)求
看過我上幾篇文章的文章大家都大致清楚,約定式請(qǐng)求可以很好的簡化請(qǐng)求封裝的復(fù)雜度,同樣的當(dāng)你公司存在小白或者是實(shí)習(xí)生的話,對(duì)于請(qǐng)求的拆封是沒有考慮的,當(dāng)你交付一個(gè)任務(wù),完成并不是等于較為好的完成。
約定式除了減少新手開發(fā)者在團(tuán)隊(duì)中不穩(wěn)定的代碼因素的同時(shí),也減少了開發(fā)時(shí)一個(gè)個(gè)的寫 AxiosPromise?函數(shù)的重復(fù)行為。下面是一個(gè)基本的接口約定,在 login-api.js?下寫的文件,都將被映射成為 請(qǐng)求函數(shù)
export?default?{
??getPerson:?'GET?/person',
??setPerson:?'POST?/person',
??updatePerson:?'PUT?/person/:id',
??deletePerson:?'DELETE?/person/:id'
}
如 log.js?打印的結(jié)果,團(tuán)隊(duì)開發(fā)人員不需要關(guān)注函數(shù)本身,只需要關(guān)注調(diào)用。同時(shí), 開發(fā)環(huán)境下?所有的接口信息都會(huì)通過 console.table?輸出到控制臺(tái),在沒有很好的類型推導(dǎo)的情況下,依舊可以快速的調(diào)用對(duì)應(yīng)接口來獲取后端數(shù)據(jù)。
本身 api 函數(shù)拆分出來,其實(shí)都是一個(gè)重復(fù)的工作,對(duì)開發(fā)者成長是毫無意義的。
不同的調(diào)用方式
為了統(tǒng)一的調(diào)用,也適當(dāng)?shù)慕o出了兩種使用方式,大多數(shù)場(chǎng)景下使用都是通用的,第一種方式較為的保守,其本質(zhì)上是交由成員來處理任務(wù),實(shí)例:
上述實(shí)例非常的簡單,相信有一點(diǎn)基礎(chǔ)的同學(xué)都可以看得出來,第一種方法非常的普遍,適用于大多數(shù)人群,但是弊端也很明顯,如果每一個(gè)接口都需要做一次 then & catch & finally?的話無疑是一個(gè)災(zāi)難,因此第二種方法誕生了,對(duì)于新手來說,更加的友好。如下實(shí)例:
在原先 api 的基礎(chǔ)上, useServices?為 Promise?的行為包裹了一層中間件,當(dāng)你決定使用非常態(tài)請(qǐng)求時(shí),這個(gè) promise中間件 行為會(huì)被觸發(fā)。且將 Promise 后的結(jié)果形態(tài)抽象成為了一個(gè)數(shù)組返回出來,那么在邏輯塊中,我們只需要簡單的通過 async & await?對(duì)結(jié)果中的數(shù)據(jù)進(jìn)行處理,而不必關(guān)注無意義的 try catch?和 then catch?。
兼容兩種方式的原因是不同開發(fā)者不同習(xí)慣問題,有些時(shí)候開發(fā)者認(rèn)為,錯(cuò)誤的處理還是交由處理人去解決,從而達(dá)到錯(cuò)誤解決目的。
Mixin 數(shù)據(jù)管理 (model)
有了約定式的請(qǐng)求,很統(tǒng)一的解決我們請(qǐng)求的問題,但隨之而來的就是異步數(shù)據(jù)的管理問題,很長一段時(shí)間中,Vue 開發(fā)者都習(xí)慣性的將接口請(qǐng)求,數(shù)據(jù)邏輯處理放在 vue 文件中,比如最常見的 分頁表格數(shù)據(jù)?, 基礎(chǔ)表單顯示,每一個(gè)頁面中都聲明了非常多的 total?, pageSize?, currentPage?,tableData?等字段,并且樂此不疲的反復(fù) CV,結(jié)束忙碌的一天后美滋滋覺得今天又完成了 10 多個(gè)頁面。其實(shí)細(xì)心的同學(xué)也發(fā)現(xiàn)了,不管你 CV 多少次代碼,對(duì)自身的提升是有限度的,無非就是孰能生巧,復(fù)制粘貼的速度更加快了,就好比你寫了 4000 次 hello?不代表你有了 4000 個(gè)詞匯一般。
因此就產(chǎn)生了封裝自己的表格組件,只需要傳遞很小一部分參數(shù)進(jìn)去(如 HTTP 請(qǐng)求方法),就可以達(dá)到渲染表格的實(shí)現(xiàn)。同樣的,也有小伙伴們封裝了 Global Mixin?來解決這部分的任務(wù)。同樣的,為了很好的管理數(shù)據(jù)層,我也在嘗試不同的數(shù)據(jù)管理,隨著業(yè)務(wù)邏輯增大,大部分的頁面的異步數(shù)據(jù)都難以管理,或多或少會(huì)和頁面的邏輯數(shù)據(jù)混淆,過一段時(shí)間后,需要將 $data?中的數(shù)據(jù)解構(gòu)重新梳理,才能泡通邏輯。
因此,在嘗試不同的解決方案后, mixin?成了首當(dāng)其沖的方案,它并不像 vuex?一般會(huì)在全局生效,而只對(duì)混入的頁面生效,所以在簡單的嘗試后,對(duì) mixin 進(jìn)行了包裝,抽象成為了一個(gè) model?層,這個(gè) model?層的作用主要是處理菜單級(jí)頁面的異步數(shù)據(jù)的流向打造的,視圖頁面數(shù)據(jù)在 .vue?中聲明, 后端數(shù)據(jù)?在 model.js?中。
一個(gè)基本的 model.js 它看起來是這樣的
export?default?{
??namespace:?'Home',
??state:?{
????move:?{},
????a:?1,
????b:?2
??},
??actions:?{
????
????async?setUser?(state,?{?payload,?set?})?{
??????const?data?=?await?test()
??????await?set(state,?'move',?data)
??????return?state.move
????}
??}
}
const?test?=?()?=>?{
??return?new?Promise(resolve?=>?{
????setTimeout(()?=>?{
??????resolve({
????????user:?'wangly',
????????age:?21
??????})
????},?2000)
??})
}
那么在頁面中,聲明的組件都會(huì)被傳入到 useModels?中進(jìn)行混入,混入后的 Mixin?命名格式已經(jīng)比較復(fù)雜了,這個(gè)時(shí)候來使用的就不是當(dāng)前的 this.xxx?,而是統(tǒng)一執(zhí)行 this.useDispatch?進(jìn)行處理,并沒有直接去觸發(fā) model methods?,同樣的對(duì)所有的 model?狀態(tài)都在發(fā)生改變,內(nèi)部會(huì)有不同的 loading。
一個(gè)簡單的實(shí)例
通過一個(gè)簡單的實(shí)例來模擬一次服務(wù)端數(shù)據(jù)加載,從無到有的過程,純 model.js?控制數(shù)據(jù)和狀態(tài) 通過下面 test 模擬一個(gè)數(shù)據(jù)接口,在 getDesserts?進(jìn)行獲取,為了保證閱讀質(zhì)量,模擬的數(shù)據(jù)就截?cái)嗔?,可以參?vuetifyUI Table Demo 數(shù)據(jù)。
export?default?{
??namespace:?'Admin',
??state:?{
????mockTabData:?[],
????headers:?[
??????{?text:?'Dessert?(100g?serving)',?value:?'name'?},
??????{?text:?'Calories',?value:?'calories'?},
??????{?text:?'Fat?(g)',?value:?'fat'?},
??????{?text:?'Carbs?(g)',?value:?'carbs'?},
??????{?text:?'Protein?(g)',?value:?'protein'?},
??????{?text:?'Iron?(%)',?value:?'iron'?}
????]
??},
??actions:?{
????
????async?getDesserts?(state,?{?payload,?set?})?{
??????const?data?=?await?test()
??????console.log(data)
??????if?(data)?{
????????state.mockTabData?=?data
??????}
????}
??}
}
const?test?=?()?=>?{
??return?new?Promise(resolve?=>?{
????setTimeout(()?=>?{
??????resolve([
????????{
??????????name:?'Frozen?Yogurt',
??????????calories:?159,
??????????fat:?6.0,
??????????carbs:?24,
??????????protein:?4.0,
??????????iron:?'1%'
????????},
????????
??????])
????},?2000)
??})
}
在頁面中,在 created?鉤子中,通過調(diào)用 this.useDispatch('Admin/getDesserts')?進(jìn)行數(shù)據(jù)獲取,然后將 Admin.headers?, Admin.mockTabData?賦值到對(duì)應(yīng)的組件參數(shù)上去,同時(shí)通過 當(dāng)前model?方法的副作用進(jìn)行骨架屏的控制。
所有的
model?方法都會(huì)在data?中生成一個(gè)副作用狀態(tài),為避免沖突,data 中避免定義model?,以免被model.js?覆蓋。
??
??????????v-if="!model['Admin/getDesserts']"
??????:headers="Admin.headers"
??????:items="Admin.mockTabData"
????>
????
??????"false"?type="table">
????
??
看看效果把,非常的簡單的控制數(shù)據(jù)響應(yīng)變化:

該特性實(shí)驗(yàn)中,只作為參考。性能壓測(cè)還在進(jìn)行中 QAQ。
jsDoc 項(xiàng)目文檔
項(xiàng)目文檔是一個(gè)非常重要的事情,不要過度相信自己的代碼,如果業(yè)務(wù)大的話,3 個(gè)月左右的時(shí)間,你經(jīng)手的項(xiàng)目可能就會(huì)丟失一部分直觀的記憶,這個(gè)時(shí)候不論是你繼續(xù)維護(hù)還是新人繼續(xù)維護(hù)都是一件非常頭疼的事情,同時(shí)需要考慮的是當(dāng)項(xiàng)目進(jìn)行到一般,后面有新人加入的時(shí)候,龐大的 components?, utils?, api?都會(huì)讓新人感到無從下手的感覺,因此一份文檔就顯得格外珍貴了。那么有同學(xué)問了,我業(yè)務(wù)都忙不過,還要花時(shí)間整理文檔,其他人的事情關(guān)我什么事?
一個(gè)好的項(xiàng)目必然會(huì)有一個(gè)好的文檔,基于這類問題,所以才引入了一個(gè)文檔工具來生成文檔,在這個(gè)期間,也同時(shí)的對(duì)文檔進(jìn)行了改進(jìn),更加的貼合 vue?本身,首先就是對(duì)文檔語法 @module?進(jìn)行了改造,同時(shí)通過 @page?來聲明頁面,通過 @component?聲明公共組件,如下示例:
??2222
那么最終通過 yarn doc?命令生成文檔:
yarn doc
效果看上去是下面這樣的
可以看到,現(xiàn)在的一些注釋就已經(jīng)很規(guī)范了,但依舊不完美,主要因素是來自于 jsdoc?文檔的主題問題,如果團(tuán)隊(duì)需要的話,可以自己重構(gòu)一套出來,也相對(duì)來說簡單。
文中實(shí)例僅限參考,注釋文檔請(qǐng)移步:jsdoc
自定義開發(fā)日志 log
對(duì)于 console?的使用,當(dāng)時(shí)在看 D2Admin?的時(shí)候?qū)⑵淇寺×艘环葸^來,對(duì)于拋錯(cuò)的日志來說,我們并不需要將自身的一些 consle?也進(jìn)行收集,但是 console?之間也存在等級(jí),如果通過 console.error 進(jìn)行的話,可能會(huì)被捕捉從而傳入給后臺(tái),因此,重寫了一份 log.js 用于開發(fā)版和測(cè)試版的調(diào)試使用。
const?log?=?{}
function?typeColor?(type?=?'default')?{
??let?color?=?''
??switch?(type)?{
????case?'default':
??????color?=?'#303133'
??????break
????case?'primary':
??????color?=?'#409EFF'
??????break
????case?'success':
??????color?=?'#67C23A'
??????break
????case?'warning':
??????color?=?'#E6A23C'
??????break
????case?'danger':
??????color?=?'#F56C6C'
??????break
????default:
??????break
??}
??return?color
}
log.capsule?=?function?(title,?info,?type?=?'primary')?{
??console.log(
????`%c?${title}?%c?${info}?%c`,
????'background:#35495E;?padding:?1px;?border-radius:?3px?0?0?3px;?color:?#fff;',
????`background:${typeColor(
??????type
????)};?padding:?1px;?border-radius:?0?3px?3px?0;??color:?#fff;`,
????'background:transparent'
??)
}
log.colorful?=?function?(textArr)?{
??console.log(
????`%c${textArr.map(t?=>?t.text?||?'').join('%c')}`,
????...textArr.map(t?=>?`color:?${typeColor(t.type)};`)
??)
}
log.default?=?function?(text)?{
??log.colorful([{?text?}])
}
log.primary?=?function?(text)?{
??log.colorful([{?text,?type:?'primary'?}])
}
log.success?=?function?(text)?{
??log.colorful([{?text,?type:?'success'?}])
}
log.warning?=?function?(text)?{
??log.colorful([{?text,?type:?'warning'?}])
}
log.danger?=?function?(text)?{
??log.colorful([{?text,?type:?'danger'?}])
}
export?default?log
如下圖效果:
log.default('>>>?我是一些默認(rèn)提示')
log.primary('>>>?我是一些標(biāo)記提示')
log.success('>>>?我是一些成功提示')
log.warning('>>>?我是一些警告提示')
log.danger('>>>?我是一些錯(cuò)誤提示')

組件和頁面管理
在開發(fā)過程中,同樣養(yǎng)成一些好習(xí)慣對(duì)于項(xiàng)目體驗(yàn)會(huì)有很好的幫助,寫代碼就和針線活一樣,細(xì)心謹(jǐn)慎,邏輯分明才能學(xué)到更多,減少 P0 BUG?的出現(xiàn),如果你項(xiàng)目不趕,還一直出現(xiàn)同一個(gè)問題,感官是非常差的。因此,牢記以下小技巧,希望對(duì)你有幫助
頁面文件
在這里推薦所有的頁面級(jí)別都放在一個(gè)樹下,目錄菜單使用文件夾且默認(rèn)視圖為 index.vue?,名稱都為小寫駝峰,最好是一句小寫涵蓋如:home?, user?。等等,組件統(tǒng)一放在起始頁面的 components?下,且名稱為大駝峰帶模塊名,如 Admin?下的 Header?組件為 AdminHeader.vue?,使用時(shí)則為:?,引入時(shí),統(tǒng)一使用 @/views/admin/components/xxx?引入。菜單在深都是在一級(jí)菜單下的東西,帶上頁面名稱是為了更好的區(qū)分,防止組件混淆。
方法導(dǎo)出
很多時(shí)候,不同的團(tuán)隊(duì)成員在編寫 utils?時(shí),有使用箭頭函數(shù),也有使用 function?來聲明的,因此,在這里推薦統(tǒng)一使用 export function?的形式進(jìn)行 js?的聲明,如下方法:
import?asyncAxiosInstance?from?'@/plugin/createService'
import?currentModels?from?'@/plugin/createModel'
export?function?getEnv?()?{
??return?process.env.VUE_APP_MODE?||?'dev'
}
export?function?useModels?(component,?models,?isDispatch?=?true)?{
??const?current?=?[]
??currentModels.forEach(item?=>?{
????if?(models.includes(item.name))?{
??????current.push(item.mixin)
????}
??})
??if?(isDispatch?&&?current.length?>?0)?{
????current.push(currentModels[0].mixin)
??}
??console.log(current)
??if?(component?.mixins)?{
????const?preMixin?=?component.mixins
????component.mixins?=?current.concat(preMixin)
????return?component
??}
??component.mixins?=?[...current]
??console.log(component)
??return?component
}
常用的指令
日常開發(fā)中,一些指令能夠達(dá)到事半功倍的效果,但是指令需要貼合業(yè)務(wù)進(jìn)行,同時(shí)設(shè)計(jì)者在設(shè)計(jì)時(shí),同樣需要標(biāo)注文檔,方便團(tuán)隊(duì)成員查看。下面的一些指令推薦在進(jìn)行注冊(cè)掉:
v-click-outside 外部點(diǎn)擊指令:當(dāng)點(diǎn)擊非綁定元素會(huì)進(jìn)行元素隱藏 v-intersect 元素監(jiān)視器:檢測(cè)元素在用戶視圖中是否可見 v-resize 縮放監(jiān)聽器:窗口進(jìn)行縮放時(shí)的監(jiān)聽指令 v-scroll 滾動(dòng)監(jiān)視器:可以靈活觀察綁定的元素滾動(dòng)變化 v-touch 觸控監(jiān)視器:可以靈活監(jiān)視移動(dòng)端當(dāng)中的觸摸行為,并產(chǎn)生回調(diào) v-auth 權(quán)限監(jiān)視器:重寫自 v-permission?主要做按鈕級(jí)別權(quán)限校驗(yàn)和頁面權(quán)限校驗(yàn)
指令資源
使用 SASS 還是 SCSS?
現(xiàn)如今最好的 CSS擴(kuò)展語言?依舊是 SASS?和 LESS?,兩者大差不差,可以根據(jù)團(tuán)隊(duì)需要進(jìn)行更換,使用起來沒有啥差別。在開發(fā)項(xiàng)目中,對(duì)于 SASS?我是首先推薦的(非 SCSS),如果沒有熟悉使用 SASS?的同學(xué)會(huì)覺得非常反人類,但如果你的規(guī)范好的話,我想你可以看下下面的這段 SASS?代碼:
@mixin?flex?($mod:?flex,?$justifyContent:?center,?$alignItems:?center,?$direction:?initial)
??display:?$mod
??justify-content:?$justifyContent
??align-items:?$alignItems
??flex-direction:?$direction
//?end?flex?mixin?...
在寫 CSS 時(shí),都建議在末尾加上一段 end?注釋來作為邏輯符號(hào)的完成,用于區(qū)分樣式塊的代碼,防止邏輯混亂,當(dāng)大量的樣式維護(hù)較差時(shí),我想 SCSS?給的安全感是比較高的,同理,當(dāng)維護(hù)的好的時(shí)候, SASS?無疑是更加簡潔。當(dāng)然也容易出錯(cuò)。
兩者殊途同歸,可以根據(jù)團(tuán)隊(duì)成員習(xí)慣選擇。
@mixin 和 %placeholder
首先, @mixin 適合用來寫一些具有邏輯性的 css ,如最基本的 flex ,可以通過傳遞的 params 進(jìn)行不同的設(shè)置,這是 %placeholder 欠缺的,但是 %placeholder 在靜態(tài)樣式的繼承上,可以減少重復(fù) css 的調(diào)用,減少重復(fù)代碼,運(yùn)用的多數(shù)場(chǎng)景為:基本卡片樣式 , 統(tǒng)一的組件樣式 等設(shè)計(jì)稿無偏差的時(shí)候使用,因此不需要無腦使用 @mixin ,有時(shí)候 %placeholder 更香。
使用一個(gè)實(shí)例進(jìn)行比對(duì):
%demo
??color:?red
??font-size:?20px
??border:?1px?solid?red
?//?end?...
.test1
??@extend?%demo
//?end?...
.test2
??@extend?%demo
//?end?...
.test3
??@extend?%demo
復(fù)制代碼
如上代碼,使用 %placeholder 最終會(huì)生成的樣式是下面這樣的:
.test1,?.test2,?.test3?{
??color:?red
??font-size:?20px
??border:?1px?solid?red
}
而如果換成 @mixin ,他們的結(jié)果是這樣的:
@mixin?demo()
??color:?red
??font-size:?20px
??border:?1px?solid?red
//?end?...
.test1
??@include?demo()
//?end?...
.test2
??@@include?demo()
//?end?...
.test3
??@@include?demo()
//?end?...
編譯后:
.test1?{
??color:?red
??font-size:?20px
??border:?1px?solid?red
}
.test2?{
??color:?red
??font-size:?20px
??border:?1px?solid?red
}
.test3?{
??color:?red
??font-size:?20px
??border:?1px?solid?red
}
不用我說,你應(yīng)該知道怎么用了吧。
ESLint
理想的情況下,大部分前端團(tuán)隊(duì)都會(huì)存在有 Eslint?,作為一個(gè)代碼質(zhì)量的標(biāo)準(zhǔn),但也僅僅只是一個(gè)標(biāo)準(zhǔn),配合 Git Commit?前置動(dòng)作可以執(zhí)行代碼檢閱是否合格來防止低于標(biāo)準(zhǔn)的代碼提交到存儲(chǔ)庫中,這一個(gè)動(dòng)作需要開發(fā)者自身養(yǎng)成良好的編碼習(xí)慣和代碼質(zhì)量意識(shí)。
如果使用的是 VS CODE?那么就需要在編譯器中進(jìn)行配置來開啟規(guī)則檢查,當(dāng)違背了語法警告的同時(shí),會(huì)提示如下警告:
不推薦直接 commit 時(shí)直接編譯化代碼,Eslint 是幫助開發(fā)者代碼成長的,而不是一個(gè)表面功夫的工具。
源碼和資源
jsDoc: 立即前往 源碼地址:立即前往 vuetifyjs:立即前往 model 管理數(shù)據(jù)思考:點(diǎn)擊前往 api 約定式: 點(diǎn)擊前往
總結(jié)
不知不覺兩個(gè)月沒寫文章了,除了換工作后確實(shí)更忙了之外,有時(shí)間都在陪一個(gè)人和看文學(xué)書,看到很多朋友轉(zhuǎn)載我的文章感到非常的驚喜,同時(shí)也對(duì)文章質(zhì)量要求更高了,隨著工作經(jīng)驗(yàn)和技術(shù)學(xué)習(xí)的累加,希望文章的內(nèi)容對(duì)你們是有技術(shù)上的提升的。
這一篇文章應(yīng)該是承接上一篇 Vue開發(fā)中的一些常見套路和技巧(上) 的下卷,相對(duì)于上來說,這篇文章東西更加的多,也更加實(shí)用,除了推動(dòng)個(gè)人開發(fā)者外,更多的是團(tuán)隊(duì)開發(fā)上思考。前端工程化慢慢的變得完善,團(tuán)隊(duì)建設(shè)變得至關(guān)重要,幾年前,還沒有前端架構(gòu)的存在,到如今前端架構(gòu)在開發(fā)中變得至關(guān)重要。都是時(shí)代的弄潮,只有不斷學(xué)習(xí),思考才能在風(fēng)起云涌的浪花上,冒出一點(diǎn)零星的水花。
深夜寫文,作為一個(gè) Vue + React 的小前端分享的一篇 Vue 文章,如果對(duì)你,或者對(duì)你團(tuán)隊(duì)有幫助,點(diǎn)個(gè)贊給作者換件衣服過冬穿吧。冬天的杭州確實(shí)很冷呀。
關(guān)注數(shù):10億+?文章數(shù):10億+
粉絲量:10億+?點(diǎn)擊量:10億+
?
懸賞博主專區(qū)請(qǐng)掃描這里

喜愛數(shù):?1億+?發(fā)帖數(shù):?1億+
回帖數(shù):?1億+?結(jié)貼率:?99.9%
—————END—————
喜歡本文的朋友,歡迎關(guān)注公眾號(hào)?程序員哆啦A夢(mèng),收看更多精彩內(nèi)容
點(diǎn)個(gè)[在看],是對(duì)小達(dá)最大的支持!
如果覺得這篇文章還不錯(cuò),來個(gè)【分享、點(diǎn)贊、在看】三連吧,讓更多的人也看到~


