久等了,提高開發(fā)效率的Vue 技巧來了
最近倆月正好用 vue 做了一個(gè)大數(shù)據(jù)的項(xiàng)目,積累了很多心得。今天終于有機(jī)會(huì)分享出來了。
組件(component)的使用
vue 提供的模塊化無疑是提高開發(fā)效率的神器,而且對(duì)于后期代碼優(yōu)化和維護(hù)也提供的極大地便利。
組件使用簡介
vue 提供了組件功能,組件又可以分為全局組件和非全局組件。區(qū)別是全局組件你可以直接在 .vue 文件中直接使用自定義的 html 即可。非全局組件必須在 Vue 的對(duì)象中定義 components 引入這個(gè)組件
- 局部組件引用方式
- import A from '@/component/A'
- export default {
- data () {},
- components: { A }
- }
- 全局組件引用方式
- // index.js 文件
- import A from '@/component/A'
- A.install = function (Vue) {
- Vue.component(A.name, A)
- }
- export {
- A
- }
- // main.js 文件
- import { A } from './components/index'
- Vue.use(A)
這里針對(duì)引入全局組件有一個(gè)優(yōu)化小技巧,上面的方式引入全局組件需要同時(shí)維護(hù) index.js 文件和 main.js 文件很麻煩。采用下面的代碼可以只維護(hù) index.js 文件即可
- // index.js 文件
- import A from '@/component/A'
- A.install = function (Vue) {
- Vue.component(A.name, A)
- }
- function InstallAll(Vue) {
- Vue.use(A)
- }
- export {
- A,
- InstallAll
- }
- // main.js 文件
- import { InstallAll } from './components/index'
- InstallAll(Vue)
驗(yàn)證碼組件的復(fù)用
手機(jī)號(hào) + 驗(yàn)證碼進(jìn)行登錄已經(jīng)是目前主流的登錄方式之一了。但是一個(gè)項(xiàng)目要使用驗(yàn)證碼的地方非常多,像登錄、注冊(cè)、修改密碼、信息再次確認(rèn)的時(shí)候都會(huì)進(jìn)行二維碼請(qǐng)求。每個(gè)地方重寫驗(yàn)證碼邏輯很麻煩,所以驗(yàn)證碼是需要抽象出來的組件的。
驗(yàn)證碼通常會(huì)對(duì)接多個(gè)接口,或者是一個(gè)接口但是需要傳遞獲取驗(yàn)證碼的類型。而這些接口通常都需要一個(gè)手機(jī)號(hào)。因此驗(yàn)證碼需要接收倆個(gè)參數(shù):phone, type。自身完成單擊操作和讀秒操作即可,不需要對(duì)引用的地方產(chǎn)生任何影響。
- // 最后每個(gè)頁面調(diào)用的時(shí)候大概長這個(gè)樣子
- <auth-code :phone="phone" type="1"></auth-code>
收藏組件的復(fù)用
收藏功能使用的頻率要比驗(yàn)證碼更高,當(dāng)然也更難。
像我最近做的大數(shù)據(jù)項(xiàng)目,用戶可以對(duì)視頻、音樂、話題進(jìn)行收藏。同時(shí)他們出現(xiàn)的地方也非常多,像視頻列表、音樂列表、話題列表、視頻詳情、音樂詳情、話題詳情... ... 都會(huì)有收藏的功能,不抽象成一個(gè)組件同樣的邏輯寫好幾個(gè)地方后期維護(hù)是及其困難的。
像這種收藏,通常都會(huì)需要一個(gè) id,是否收藏狀態(tài),以及完成收藏后的一系列的跳轉(zhuǎn)功能。因此需要倆個(gè)參數(shù): id 和 status。和 complete 回調(diào)方法
- // 最后每個(gè)頁面調(diào)用的時(shí)候大概長這個(gè)樣子
- <collection :id="id" :status="status" @complete="complete"></collection>
我上面提到我會(huì)收藏音樂、視頻、話題,很顯然是三個(gè)收藏接口。難道要寫三個(gè)收藏組件么?當(dāng)然不是,既然同屬于收藏功能,自然是一個(gè)組件搞定了。再加一個(gè) type 參數(shù)區(qū)別一下即可了
- // 最后每個(gè)頁面調(diào)用的時(shí)候大概長這個(gè)樣子
- <collection :id="id" :status="status" type="video" @complete="complete"></collection>
這樣每次用到收藏的時(shí)候我只需要復(fù)制這一行代碼就可以了
總結(jié)
第三方 UI 庫會(huì)給我們引入非常多好用的組件,像輪播圖、表單、圖片上傳。但是這些都是跟業(yè)務(wù)無關(guān)的組件,而我們?cè)谧鲰?xiàng)目的時(shí)候時(shí)候肯定會(huì)碰到大量重復(fù)的功能。為了代碼的易維護(hù)性一定要有良好的組件抽象能力。合理運(yùn)用好 component 功能。
上面提到的驗(yàn)證碼和收藏功能使用次數(shù)頻繁,我通常都會(huì)當(dāng)做全局組件處理(個(gè)人會(huì)把使用次數(shù) > 1 的組件當(dāng)成全局組件),但是有的頁面及其復(fù)雜,一個(gè)頁面上萬行代碼后期查找肯定費(fèi)事巴拉的。也一定要對(duì)其進(jìn)行拆分處理不要一個(gè)組件寫到尾。針對(duì)這種情況我通常都會(huì)采用局部組建去維護(hù),提高界面的簡潔程度。
filters 使用技巧
數(shù)據(jù)過濾無疑也是 vue 的重要功能之一。像時(shí)間、數(shù)字的過濾,實(shí)在是太頻繁了。掌握 filter 無疑能大大提高代碼幸福度和可維護(hù)性
filter 使用簡介
同 component 一樣 filter 也分為全局過濾器和局部過濾器。
- 全局過濾器
- vue.filter('date', function (value1, value2, ...) {
- return '處理之后的結(jié)果'
- })
- 局部過濾器
- export default {
- filters: {
- date (value1, value2, ...) {
- return '處理之后的結(jié)果'
- }
- }
- }
- 使用方式(不管是全局的還是局部的使用方式都一樣):
- // 不帶參數(shù)
- {{value1 | date}}
- // 帶參數(shù)
- {{value1 | date(value2, ...)}}
- // 多個(gè)過濾器
- {{value1 | filter1 | filter2}}
注意:第一個(gè)參數(shù)是管道符 (|) 前面的值
常見的使用場(chǎng)景
我大部分都是使用的全局過濾器。像局部過濾器,一是獲取到原始數(shù)據(jù)的時(shí)候可以直接進(jìn)行處理,二是發(fā)現(xiàn)早期使用的局部過濾器都升級(jí)為全局過濾器了。如果你有好的局部過濾器場(chǎng)景歡迎評(píng)論
- 日期處理。后端傳的數(shù)據(jù)要么是 2019-03-14 09:00:00 這種字符串類型的。要么就是時(shí)間戳類型的,但是界面通常只會(huì)展示一部分,比如只展示年月日,或者是月日啊。因此有個(gè)全局 date 過濾器,幸福到哭。這個(gè)過濾器最好是同時(shí)支持以上倆種格式。要是不知道
- 數(shù)字處理。像保留幾位小數(shù)、超過多少位以字母 w 代替,或者是漢字“億”都很常見
上面?zhèn)z種是我碰到的最多的,也歡迎你評(píng)論補(bǔ)充。
總結(jié)
該用 filters 的地方千萬別手軟,超過一處就要寫成公共的。否則后期要是邏輯處理的不對(duì),你不知道哪些地方用了相同的處理邏輯很容易造成 bug 漏改的情況。
mixins 使用場(chǎng)景
這個(gè)屬性也分為全局和局部使用,全局使用了將會(huì)對(duì)之后的所有組件產(chǎn)生影響。因此我不建議在業(yè)務(wù)代碼中使用全局 mixins。而且感覺全局 mixins 使用起來不利于代碼維護(hù),你想突然在 template 中使用了一個(gè)一個(gè)函數(shù)第一想法肯定是去 methods 中查找,找不到就很難受了。而且破壞性也比較大,所以我都采用局部注入的方式。讓別人知道這里采用了 mixins,要是遇到了一些奇怪的情況,他知道這里有 mixins 就會(huì)主動(dòng)去這里面查看相關(guān)代碼了。
這個(gè)屬性我用的最多的是引用第三方的列表庫的時(shí)候他通常都會(huì)有個(gè) formatter 的格式化數(shù)據(jù)屬性。這里 filters 是用不了的。但像列表對(duì)于數(shù)據(jù)的處理重復(fù)性是特別多的,因此 注入一個(gè) mixins 就方便多了。
一些第三方庫時(shí)用到的技巧
router 中用到的一些技巧
鉤子函數(shù) beforeEach 做路由跳轉(zhuǎn)的時(shí)候會(huì)先執(zhí)行 beforeEach 。因此你可以在路由跳轉(zhuǎn)的時(shí)候進(jìn)行判定是否可以跳轉(zhuǎn),常見場(chǎng)景就是判定用戶是否登錄,有沒有某個(gè)頁面的權(quán)限
- // to: Route: 即將要進(jìn)入的目標(biāo) 路由對(duì)象
- // from: Route: 當(dāng)前導(dǎo)航正要離開的路由
- // next: Function: 一定要調(diào)用該方法來 resolve 這個(gè)鉤子。執(zhí)行效果依賴 next 方法的調(diào)用參數(shù)。
- next(): 進(jìn)行管道中的下一個(gè)鉤子。如果全部鉤子執(zhí)行完了,則導(dǎo)航的狀態(tài)就是 confirmed (確認(rèn)的)。
- router.beforeEach((to, form, next) => {})
vuex 中用到的一些技巧
action 的技巧 action 是可以異步執(zhí)行方法的。我在業(yè)務(wù)中通常會(huì)遇到這樣的情況:獲取某種信息,但是這個(gè)信息接口多個(gè)頁面都用到了,每個(gè)頁面都處理一下這個(gè)接口真的很麻煩。所以傳入 vuex 中共享這部分信息就十分幸福了。因?yàn)槭钱惒降乃杂玫搅?action。提供一個(gè)參考代碼:
- actions: {
- getMemberShip ({ state, commit }) {
- return new Promise((resolve, reject) => {
- if (!state.memberShip) {
- // memberShip 為 ajax 請(qǐng)求方法
- memberShip(state.userInfo).then(res => {
- commit('setMemberShip', res)
- resolve(res)
- }).catch(err => {
- reject(err)
- })
- } else {
- resolve(state.memberShip)
- }
- })
- },
- }
這個(gè)是我定義的一個(gè)獲取會(huì)員套餐的情況,會(huì)員套餐很多個(gè)頁面都會(huì)用到。但是他改動(dòng)次數(shù)頻繁,而且也沒必要用戶一登錄就去加載,因此使用 action 存起來。如果沒有這個(gè)值就執(zhí)行 ajax 請(qǐng)求,如果有就直接返回結(jié)果。
echarts
echarts 圖表界的老大哥了,支持 N 多種圖表,配置項(xiàng)說好幾千應(yīng)該沒夸大其詞吧。不過也正因?yàn)榉倍嗟呐渲庙?xiàng)才給了你更多的自由配置的可能。那用 echarts 有什么技巧呢?
快速定位配置項(xiàng)
echarts 包含標(biāo)題、圖例、提示框、標(biāo)注、標(biāo)線... ... 等控件,調(diào)整個(gè)樣式真的不好找。但是現(xiàn)在官方新加入了一個(gè)術(shù)語速查手冊(cè),之前我都是去舊官方上查,現(xiàn)在新官方上有了這個(gè)東西可是有福了。我需要調(diào)整那個(gè)控件的效果在上面一點(diǎn)就帶我到相應(yīng)的 API 簡直是好用到飛起。
優(yōu)化項(xiàng)目代碼 不是專門的數(shù)據(jù)展示項(xiàng)目,用到的圖表類型其實(shí)不多。通常是一個(gè)圖表反復(fù)用,而 echarts 配置一個(gè)圖表通常都好幾十行代碼。把這個(gè)配置項(xiàng)拿出去只傳進(jìn)來一個(gè)參數(shù)代碼多整潔。這個(gè)實(shí)現(xiàn)特別簡單,要是還沒這么做建議馬上優(yōu)化你的項(xiàng)目哦
axios
axios 是類似于 ajax 的的第三方控件。所以這個(gè)我也是蠻有想法跟大家交流的。
我在開發(fā)中遇到一個(gè)坑,官方文檔說支持 IE,但是 IE 壓根不支持。是因?yàn)?axios 底層是用 promise 寫的,IE 壓根還不支持這個(gè)屬性,因此需要引入 profill 。解決辦法是引入 babel-polyfill
- // 步驟1
- npm install --save babel-polyfill
- // 步驟2 在 vue.config.js 文件中加入以下內(nèi)容
- module.exports = {
- configureWebpack: config => {
- return {
- entry: {
- app:['babel-polyfill', './src/main.js']
- }
- }
- }
- }
擁有自己的 axios 默認(rèn)配置 這個(gè)代碼過長,我就不分享了。想要可以關(guān)注公眾號(hào)入群交流(二維碼在底部)
總結(jié)
本來還想在醞釀醞釀,不過近期發(fā)現(xiàn)在不總結(jié)一下自己就快漸漸的忘記了,其中還有很多東西沒寫出來,像項(xiàng)目優(yōu)化技巧,指令系統(tǒng)。但是這篇文字已經(jīng)很長了。所以只能到這里了,