總結(jié)我對Vue項目團隊開發(fā)的一些基本配置封裝分享
關注公眾號?前端人,回復“加群”
添加無廣告優(yōu)質(zhì)學習群
總結(jié)我對Vue項目團隊開發(fā)的一些基本配置封裝分享
簡介
本篇文章主要帶來的是 vue 基礎架構(gòu) 篇,大家都知道, Vue3.0 后 Vue2.0 會有一個終結(jié)版出來,也就說明 Vue 迎來了新時代,但是并不是所有項目都能夠一起邁向新時代的輪船。
本文主要是承接上篇優(yōu)化的技巧文章做一個續(xù)篇吧,這個續(xù)篇主要是針對團隊開發(fā)相關的東西,相關插件和庫只是微微帶過,如果本文能夠推動你們的生產(chǎn)線,就點個贊吧。
配置相關類的可以去搜索對應的分享貼,或者看我之前的文章,本文內(nèi)容較為貼合團隊開發(fā),非工具鏈分享文,大部分都能引發(fā)一些技術層面的思考。
前言
在很多時候,對于 vue 項目來說,很多剛?cè)腴T,或者是受業(yè)務妥協(xié)的朋友大都是從百度 CV 一套看得過去的架子,如常見的 D2Admin , vue-element-admin ,進行一個二次迭代的開發(fā),其項目本身非常的優(yōu)質(zhì),而在其 template 中去進行一個更改能夠使得項目在一開始有一個很好的基礎環(huán)境,但是如果沒有花時間去琢磨透其中三分明細。
在后續(xù)排雷來說,無疑是非常的困難的,因此大部分前端團隊都會重構(gòu)出自己的一套基礎腳手架封裝,有通過 webpack進行處理的,也有基于 VueCli 打造的,最終都是自身團隊的財產(chǎn),從技術分享都細分實踐都能給團隊的小伙伴或多或少帶來一些開發(fā)上面的便利。
對后續(xù)團隊人員的變動也能快速的投入生產(chǎn)當中。
做了什么?
基本HTTP請求封裝 約定式HTTP請求管理 Mmixin數(shù)據(jù)管理 jsdoc項目文檔 log異常處理 組件和頁面管理 常用的指令 使用sass還是scss? @mixin 和 %placeholder eslint 基本HTTP請求做了什么? 錯誤處理
在這里選用的是現(xiàn)如今兼容性比較好的 axios ,可以說是比較好的一個請求庫,相比于 fetch 來說,兩者各有優(yōu)勢,(我已經(jīng)開始使用 fetch )。這一部分其實無非就是封裝一些公共調(diào)用時需要處理的行為,如:token , 請求攔截 , 響應攔截 , 錯誤碼約定 , 異常上報 , 中間件 等一系列基礎的行為模式。
如下實例,當 HTTP 請求出現(xiàn)錯誤的時候,首先通過 getEnv 獲取當前的開發(fā)環(huán)境,如果是 dev(開發(fā)環(huán)境下) 只做一個簡單的 console.log,非開發(fā)環(huán)境下,則是上報進行異常監(jiān)聽,對于前后端來說都
/**
?*?異常錯誤處理
?*?@example
?*?handleError?('我發(fā)生了錯誤',?'后端約定message')
?*?@param?{?string?}?error?console錯誤信息
?*?@param?{?string?}?msg?后端message捕獲
?*/
function?handleError?(/*?@type?{?string?}?*/?error,?/*?@type?{?string?}?*/msg)?{
??if?(getEnv()?===?'dev')?{
????tools.log.danger('>>>>>>?HTTP?Error?>>>>>>')
????console.log(error,?msg)
??}?else?{
????Store.dispatch('logs/push',?{
??????message:?msg,
??????type:?'danger'
????})
??}
}
RESTFul 相對于一些攔截器來說,都非常的簡單,需要注意的無非就是根據(jù)團隊的一些規(guī)范制定一些規(guī)則,如常見的 code 碼等方法,大部分情況下,如無意外,99%的接口都是請求成功的,但因為特殊性,內(nèi)部會有一個 code 的狀態(tài)來定義正反向。同樣的,在操作接口時,一些狀態(tài)也是需要和接口的請求方式同步,參考如下:
GET: 200 OK POST: 201 Created PUT: 200 OK DELETE: 204 No Content
現(xiàn)如今大部分的接口的規(guī)范都使用 RESTful ,如果不知道 RESTful 是什么,可以看看 @阮一峰 的文章來初步了解。RESTful API 最佳實踐@阮一峰的網(wǎng)絡日志
狀態(tài)碼機制
同樣的 code 中我們也自定義日常開發(fā)中的一些狀態(tài)碼,當我們需要用到 第三方API 的時候,前后端都需要快速的定位是自身服務的問題,還是其他服務(例如中臺)的問題,因此對接服務我們都自定義了一些 code 來陳述這一類錯誤的處理。可以參考如下,這些其實都是創(chuàng)建在一個對象當中的:image.png自定義code
code 狀態(tài) 描述 30000 invalid credential 不合法的憑證 30001 invalid connect_type 不合法的connect_type 30001 invalid group_conf_id 不合法的group_conf_id ...... ...... ......
當我們細化一些異常時,這時候是可以劃分的非常細致的,這里給出微信的一些參考:
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 缺失二進制媒體文件 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超時 42002 refresh_token expired refresh_token超時
/**
?*?HTTP請求處理
?*?@param?{?object?}?settings?請求設置
?*?@param?{?string?}?[settings.withCredentials]?安全策略
?*?@param?{?number?}?[settings.timeout]?超時時間
?*?@param?{?string?}?[settings.baseURL]?接口地址
?*?@return?{?Promise?}?HTTP請求方法
?*/
function?createHttpService?(/*?@type?{?object?}?*/settings)?{
??const?service?=?Axios.create(settings)
??service.interceptors.request.use(
????config?=>?{
??????//?TODO:?添加token
??????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('>>>?自定義錯誤信息,全局提示處理',?message)
????????return?data
??????}
??????//?正常的code
??????if?(code?>=?200?&&?code?300)?{
????????return?data
??????}
??????//?錯誤的code,?自己處理
??????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請求
約定式請求可以很好的簡化請求封裝的復雜度,同樣的當你公司存在小白或者是實習生的話,對于請求的拆封是沒有考慮的,當你交付一個任務,完成并不是等于較為好的完成。
約定式除了減少新手開發(fā)者在團隊中不穩(wěn)定的代碼因素的同時,也減少了開發(fā)時一個個的寫 AxiosPromise 函數(shù)的重復行為。下面是一個基本的接口約定,在 login-api.js 下寫的文件,都將被映射成為 請求函數(shù)
//?login-api.js
export?default?{
??getPerson:?'GET?/person',
??setPerson:?'POST?/person',
??updatePerson:?'PUT?/person/:id',
??deletePerson:?'DELETE?/person/:id'
}
如 log.js 打印的結(jié)果,團隊開發(fā)人員不需要關注函數(shù)本身,只需要關注調(diào)用。同時, 開發(fā)環(huán)境下 所有的接口信息都會通過 console.table 輸出到控制臺,在沒有很好的類型推導的情況下,依舊可以快速的調(diào)用對應接口來獲取后端數(shù)據(jù)。image.png
本身api函數(shù)拆分出來,其實都是一個重復的工作,對開發(fā)者成長是毫無意義的。
不同的調(diào)用方式
為了統(tǒng)一的調(diào)用,也適當?shù)慕o出了兩種使用方式,大多數(shù)場景下使用都是通用的,第一種方式較為的保守,其本質(zhì)上是交由成員來處理任務,實例:
?//?引入useServices
import?{?useServices?}?from?'framework'
//?解構(gòu)接口函數(shù)
const?{?getPerson?}?=?useServices()
/**
?*?@module?測試頁面1
?*?@page
?*/
export?default?{
??name:?'home',
??created?()?{
????//?請求后處理
????getPerson().then(res?=>?{
??????console.log(res)
??????alert('接口請求成功')
????},?err?=>?{
??????console.log(err)
??????alert('接口請求失敗')
????})
??}
}
上述實例非常的簡單,相信有一點基礎的同學都可以看得出來,第一種方法非常的普遍,適用于大多數(shù)人群,但是弊端也很明顯,如果每一個接口都需要做一次 then & catch & finally 的話無疑是一個災難,因此第二種方法誕生了,對于新手來說,更加的友好。
如下實例:
?//?引入useServices
import?{?useServices?}?from?'framework'
/**
?*?@module?測試頁面2
?*?@page
?*/
const?Admin?=?{
??created?()?{
????this.getPersonData()
??},
??methods:?{
????//?獲取數(shù)據(jù)
????async?getPersonData?()?{
??????const?[,?err]?=?await?useServices('getPerson')
??????if?(err)?{
????????alert('接口請求失敗')
??????}?else?{
????????alert('接口請求成功')
??????}
????}
??}
}
export?default?Admin
在原先api的基礎上, useServices 為 Promise 的行為包裹了一層中間件,當你決定使用非常態(tài)請求時,這個 promise中間件 行為會被觸發(fā)。且將 Promise 后的結(jié)果形態(tài)抽象成為了一個數(shù)組返回出來,那么在邏輯塊中,我們只需要簡單的通過 async & await 對結(jié)果中的數(shù)據(jù)進行處理,而不必關注無意義的 try catch 和 then catch 。
兼容兩種方式的原因是不同開發(fā)者不同習慣問題,有些時候開發(fā)者認為,錯誤的處理還是交由處理人去解決,從而達到錯誤解決目的。
Mixin數(shù)據(jù)管理(model)
有了約定式的請求,很統(tǒng)一的解決我們請求的問題,但隨之而來的就是異步數(shù)據(jù)的管理問題,很長一段時間中,Vue開發(fā)者都習慣性的將接口請求,數(shù)據(jù)邏輯處理放在vue文件中,比如最常見的 分頁表格數(shù)據(jù) , 基礎表單顯示,每一個頁面中都聲明了非常多的 total , pageSize , currentPage ,tableData 等字段,并且樂此不疲的反復CV,結(jié)束忙碌的一天后美滋滋覺得今天又完成了10多個頁面。其實細心的同學也發(fā)現(xiàn)了,不管你CV多少次代碼,對自身的提升是有限度的,無非就是孰能生巧,復制粘貼的速度更加快了,就好比你寫了4000次 hello 不代表你有了4000個詞匯一般。
因此就產(chǎn)生了封裝自己的表格組件,只需要傳遞很小一部分參數(shù)進去(如HTTP請求方法),就可以達到渲染表格的實現(xiàn)。同樣的,也有小伙伴們封裝了 Global Mixin 來解決這部分的任務。同樣的,為了很好的管理數(shù)據(jù)層,我也在嘗試不同的數(shù)據(jù)管理,隨著業(yè)務邏輯增大,大部分的頁面的異步數(shù)據(jù)都難以管理,或多或少會和頁面的邏輯數(shù)據(jù)混淆,過一段時間后,需要將 $data 中的數(shù)據(jù)解構(gòu)重新梳理,才能泡通邏輯。
因此,在嘗試不同的解決方案后, mixin 成了首當其沖的方案,它并不像 vuex 一般會在全局生效,而只對混入的頁面生效,所以在簡單的嘗試后,對mixin進行了包裝,抽象成為了一個 model 層,這個 model 層的作用主要是處理菜單級頁面的異步數(shù)據(jù)的流向打造的,視圖頁面數(shù)據(jù)在 .vue 中聲明, 后端數(shù)據(jù) 在 model.js 中。
一個基本的model.js 它看起來是這樣的
export?default?{
??namespace:?'Home',
??state:?{
????move:?{},
????a:?1,
????b:?2
??},
??actions:?{
????/**
?????*
?????*?@param?{?Object?}?state
?????*?@param?{?Object?}?payload
?????*?@param?{?function?}?set
?????*/
????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)
??})
}
那么在頁面中,聲明的組件都會被傳入到 useModels 中進行混入,混入后的 Mixin 命名格式已經(jīng)比較復雜了,這個時候來使用的就不是當前的 this.xxx ,而是統(tǒng)一執(zhí)行 this.useDispatch 進行處理,并沒有直接去觸發(fā) model methods ,同樣的對所有的 model 狀態(tài)都在發(fā)生改變,內(nèi)部會有不同的loading。
一個簡單的實例
通過一個簡單的實例來模擬一次服務端數(shù)據(jù)加載,從無到有的過程,純 model.js 控制數(shù)據(jù)和狀態(tài) 通過下面test模擬一個數(shù)據(jù)接口,在 getDesserts 進行獲取,為了保證閱讀質(zhì)量,模擬的數(shù)據(jù)就截斷了,可以參考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:?{
????/**
?????*
?????*?@param?{?Object?}?state
?????*?@param?{?Object?}?payload
?????*?@param?{?function?}?set
?????*/
????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%'
????????},
????????//?...?省略數(shù)據(jù)
??????])
????},?2000)
??})
}
在頁面中,在 created 鉤子中,通過調(diào)用 this.useDispatch('Admin/getDesserts') 進行數(shù)據(jù)獲取,然后將 Admin.headers , Admin.mockTabData 賦值到對應的組件參數(shù)上去,同時通過 當前model 方法的副作用進行骨架屏的控制。
所有的 model 方法都會在 data 中生成一個副作用狀態(tài),為避免沖突,data中避免定義 model ,以免被 model.js 覆蓋。
<template>
??<div>
????<v-data-table
??????v-if="!model['Admin/getDesserts']"
??????:headers="Admin.headers"
??????:items="Admin.mockTabData"
????>v-data-table>
????<v-sheet?v-else>
??????<v-skeleton-loader?:boilerplate="false"?type="table">v-skeleton-loader>
????v-sheet>
??div>
template>
import?{?useModels?}?from?'framework'
/**
?*?@module?測試頁面2
?*?@page
?*/
const?Admin?=?{
??created?()?{
????this.useDispatch('Admin/getDesserts')
??}
}
export?default?useModels(Admin,?['Admin'])
看看效果把,非常的簡單的控制數(shù)據(jù)響應變化:

該特性實驗中,只作為參考。性能壓測還在進行中QAQ。
jsDoc項目文檔
項目文檔是一個非常重要的事情,不要過度相信自己的代碼,如果業(yè)務大的話,3個月左右的時間,你經(jīng)手的項目可能就會丟失一部分直觀的記憶,這個時候不論是你繼續(xù)維護還是新人繼續(xù)維護都是一件非常頭疼的事情
同時需要考慮的是當項目進行到一般,后面有新人加入的時候,龐大的 components , utils , api 都會讓新人感到無從下手的感覺,因此一份文檔就顯得格外珍貴了。那么有同學問了,我業(yè)務都忙不過,還要花時間整理文檔,其他人的事情關我什么事?
一個好的項目必然會有一個好的文檔,基于這類問題,所以才引入了一個文檔工具來生成文檔,在這個期間,也同時的對文檔進行了改進,更加的貼合 vue 本身,首先就是對文檔語法 @module 進行了改造,同時通過 @page 來聲明頁面,通過 @component 聲明公共組件,如下### 示例:
<template>
??<div>2222div>
template>
import?{?useModels,?useServices?}?from?'framework'
/**
?*?@module?測試頁面2
?*?@page
?*/
const?Admin?=?{
??created?()?{
????this.getPersonData()
??},
??data:?()?=>?({
????/**?@type?{?boolean?}?當前是否折扣??*/
????discount:?false,
????/**?@type?{?number?}?當前tab頁面?*/
????currentTab:?1
??}),
??methods:?{
????/**
?????*?獲取用戶數(shù)據(jù)
?????*?@method?getPersonData
?????*?@returns?{?void?}?-?無返回結(jié)果
?????*/
????async?getPersonData?()?{
??????const?[,?err]?=?await?useServices('getPerson')
??????if?(err)?{
????????alert('接口請求失敗')
??????}?else?{
????????alert('接口請求成功')
??????}
????}
??}
}
export?default?useModels(Admin,?['Admin'])
</script>
那么最終通過 yarn doc 命令生成文檔:
yarn?doc
效果看上去是下面這樣的image.png可以看到,現(xiàn)在的一些注釋就已經(jīng)很規(guī)范了,但依舊不完美,主要因素是來自于 jsdoc 文檔的主題問題,如果團隊需要的話,可以自己重構(gòu)一套出來,也相對來說簡單。
文中實例僅限參考,注釋文檔請移步:jsdoc
自定義開發(fā)日志log
對于 console 的使用,當時在看 D2Admin 的時候?qū)⑵淇寺×艘环葸^來,對于拋錯的日志來說,我們并不需要將自身的一些 consle 也進行收集,但是 console 之間也存在等級,如果通過 console.error 進行的話,可能會被捕捉從而傳入給后臺,因此,重寫了一份log.js用于開發(fā)版和測試版的調(diào)試使用。
const?log?=?{}
/**
?*?@description?返回這個樣式的顏色值
?*?@param?{String}?type?樣式名稱?[?primary?|?success?|?warning?|?danger?|?text?]
?*/
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
}
/**
?*?@description?打印一個?[?title?|?text?]?樣式的信息
?*?@param?{String}?title?title?text
?*?@param?{String}?info?info?text
?*?@param?{String}?type?style
?*/
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'
??)
}
/**
?*?@description?打印彩色文字
?*/
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('>>>?我是一些默認提示')
log.primary('>>>?我是一些標記提示')
log.success('>>>?我是一些成功提示')
log.warning('>>>?我是一些警告提示')
log.danger('>>>?我是一些錯誤提示')

組件和頁面管理
在開發(fā)過程中,同樣養(yǎng)成一些好習慣對于項目體驗會有很好的幫助,寫代碼就和針線活一樣,細心謹慎,邏輯分明才能學到更多,減少 P0 BUG 的出現(xiàn),如果你項目不趕,還一直出現(xiàn)同一個問題,感官是非常差的。因此,牢記以下小技巧,希望對你有幫助
頁面文件
在這里推薦所有的頁面級別都放在一個樹下 目錄菜單使用文件夾且默認視圖為 index.vue名稱都為小寫駝峰,最好是一句小寫涵蓋如: home,user。組件統(tǒng)一放在起始頁面的 components下,且名稱為大駝峰帶模塊名,如Admin下的Header組件為AdminHeader.vue使用時則為: ,引入時,統(tǒng)一使用 @/views/admin/components/xxx引入。菜單在深都是在一級菜單下的東西,帶上頁面名稱是為了更好的區(qū)分,防止組件混淆。

方法導出
很多時候,不同的團隊成員在編寫 utils 時,有使用箭頭函數(shù),也有使用 function 來聲明的,因此,在這里推薦統(tǒng)一使用 export function 的形式進行 js 的聲明,如下方法:
import?asyncAxiosInstance?from?'@/plugin/createService'
import?currentModels?from?'@/plugin/createModel'
/**
?*?獲取當前開發(fā)環(huán)境狀態(tài)
?*?@example
?*?getEnv()
?*?@export?{?Function?}?getEnv?當前環(huán)境方法【開發(fā)環(huán)境】【測試環(huán)境】【生產(chǎn)環(huán)境】
?*?@return?{String}?當前環(huán)境【dev】【test】【pro】
?*/
export?function?getEnv?()?{
??return?process.env.VUE_APP_MODE?||?'dev'
}
/**
?*?允許當前組件使用model數(shù)據(jù)依賴
?*?@param?{?object?}?component?當前的Vue組件
?*?@param?{?Array?} ?models?需要注入的模塊
?*?@param?{?boolean?}?isDispatch?是否開啟dispatch
?*?@returns?{?object?}
?*/
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ā)中,一些指令能夠達到事半功倍的效果,但是指令需要貼合業(yè)務進行,同時設計者在設計時,同樣需要標注文檔,方便團隊成員查看。下面的一些指令推薦在進行注冊掉:
v-click-outside 外部點擊指令:當點擊非綁定元素會進行元素隱藏
v-intersect 元素監(jiān)視器:檢測元素在用戶視圖中是否可見
v-resize 縮放監(jiān)聽器:窗口進行縮放時的監(jiān)聽指令
v-scroll 滾動監(jiān)視器:?可以靈活觀察綁定的元素滾動變化
v-touch 觸控監(jiān)視器:可以靈活監(jiān)視移動端當中的觸摸行為,并產(chǎn)生回調(diào)
v-auth 權(quán)限監(jiān)視器:重寫自 v-permission 主要做按鈕級別權(quán)限校驗和頁面權(quán)限校驗
使用SASS還是SCSS?
現(xiàn)如今最好的 CSS擴展語言 依舊是 SASS 和 LESS ,兩者大差不差,可以根據(jù)團隊需要進行更換,使用起來沒有啥差別。
在開發(fā)項目中,對于 SASS 我是首先推薦的(非SCSS),如果沒有熟悉使用 SASS 的同學會覺得非常反人類,但如果你的規(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時,都建議在末尾加上一段 end 注釋來作為邏輯符號的完成,用于區(qū)分樣式塊的代碼,防止邏輯混亂,當大量的樣式維護較差時,我想 SCSS 給的安全感是比較高的,同理,當維護的好的時候, SASS 無疑是更加簡潔。當然也容易出錯。
兩者殊途同歸,可以根據(jù)團隊成員習慣選擇。
@mixin 和 %placeholder
首先, @mixin 適合用來寫一些具有邏輯性的 css ,如最基本的 flex ,可以通過傳遞的 params 進行不同的設置,這是 %placeholder 欠缺的,但是 %placeholder 在靜態(tài)樣式的繼承上,可以減少重復 css 的調(diào)用,減少重復代碼,運用的多數(shù)場景為:基本卡片樣式 , 統(tǒng)一的組件樣式 等設計稿無偏差的時候使用,因此不需要無腦使用 @mixin ,有時候 %placeholder 更香。
使用一個實例進行比對:
%demo
color: red
font-size: 20px
border: 1px solid red
// end ...
.test1
@extend %demo
// end ...
.test2
@extend %demo
// end ...
.test3
@extend %demo
如上代碼,使用 %placeholder 最終會生成的樣式是下面這樣的:
.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
}
不用我說,你應該知道怎么用了吧。
ESLint
理想的情況下,大部分前端團隊都會存在有 Eslint ,作為一個代碼質(zhì)量的標準,但也僅僅只是一個標準,配合 Git Commit 前置動作可以執(zhí)行代碼檢閱是否合格來防止低于標準的代碼提交到存儲庫中,這一個動作需要開發(fā)者自身養(yǎng)成良好的編碼習慣和代碼質(zhì)量意識。
如果使用的是 VS CODE 那么就需要在編譯器中進行配置來開啟規(guī)則檢查,當違背了語法警告的同時,會提示如下警告:image.png
不推薦直接commit時直接編譯化代碼,Eslint是幫助開發(fā)者代碼成長的,而不是一個表面功夫的工具。
源碼和資源
jsDoc
github.com/jsdoc/jsdoc
源碼地址:
github.com/wangly19/vue-base-framework
vuetifyjs:
vuetifyjs.com
model管理數(shù)據(jù)思考:
juejin.cn/post/6900702340412604430
api約定式:
juejin.cn/post/6873605885868916744
總結(jié)
不知不覺兩個月沒寫文章了,除了換工作后確實更忙了之外,有時間都在陪一個人和看文學書,看到很多朋友轉(zhuǎn)載我的文章感到非常的驚喜,同時也對文章質(zhì)量要求更高了,隨著工作經(jīng)驗和技術學習的累加,希望文章的內(nèi)容對你們是有技術上的提升的。
如果對你,或者對你團隊有幫助,點個贊給作者換件衣服過冬穿吧。冬天的杭州確實很冷呀。
原文地址
juejin.cn/post/6908492497261953038

1.如果看到這里,說明你喜歡這篇文章,請?轉(zhuǎn)發(fā)、點贊、在看
2.關注公眾號前端人,回復資料包領取我整理的前端進階資料包
3.回復加群,加入前端進階群,和小伙伴一起學習討論!
