vue3开发实践总结
背景
前段時(shí)間需要排Q3的前端技術(shù)項(xiàng),剛好我一直想做vue3項(xiàng)目很久了,就與領(lǐng)導(dǎo)商議了一下,把一個(gè)線上小項(xiàng)目改造成vue3版本的。
這是個(gè)PC端項(xiàng)目,作為微前端被內(nèi)嵌至別的應(yīng)用之中,項(xiàng)目不大,只有三個(gè)界面,不過(guò)這三個(gè)界面都是基礎(chǔ)核心業(yè)務(wù)模塊,里面內(nèi)嵌了樹(shù)、動(dòng)態(tài)布局、動(dòng)態(tài)篩選等N個(gè)業(yè)務(wù)組件。
在最近一個(gè)月內(nèi),經(jīng)過(guò)斷斷續(xù)續(xù)的開(kāi)發(fā),昨天項(xiàng)目發(fā)布到生產(chǎn)環(huán)境。現(xiàn)總結(jié)一下這段實(shí)踐。
技術(shù)棧
- vue全家桶:vue3.2、vue-router4.0、pinia2.0
- 組件庫(kù):element-plus 2.2.x、vxetable 4.2.x
- 加強(qiáng)類:typescript、eslint、prettier
- 打包構(gòu)建:vite 2.9.x
- 微前端相關(guān):vite-plugin-qiankun
之所以在使用element plus的基礎(chǔ)上,又添加了vxetable的使用,是因?yàn)橹暗捻?xiàng)目表格都是使用的vxetable,后者在復(fù)雜表格的實(shí)踐上,功能是遠(yuǎn)超過(guò)element table的
具體開(kāi)發(fā)過(guò)程
- 使用的 npm init vue@latest 腳手架初始化工程
- 刪除無(wú)用代碼,引入組件庫(kù)、axios、sortable等業(yè)務(wù)包
- 業(yè)務(wù)界面、業(yè)務(wù)組件通過(guò)組合式api全部重寫(xiě)(之前的代碼已經(jīng)成了巨石應(yīng)用)
- 全局組件部分使用組合式api重寫(xiě)
- 微前端整合
- 代碼優(yōu)化、注釋,上線
ts的引入
之前開(kāi)發(fā)react的時(shí)候,使用過(guò)ts,不過(guò)開(kāi)發(fā)vue2項(xiàng)目的時(shí)候,由于其對(duì)ts支持的不友好,都沒(méi)有使用ts
由于vue3對(duì)ts支持的比較好,再加上ts目前作為前端開(kāi)發(fā)屆的標(biāo)配,沒(méi)有理解不添加使用ts
選擇組合式api(Composition API)
個(gè)人覺(jué)得是vue3相對(duì)于vue2開(kāi)發(fā)體驗(yàn)改變最大的地方,完全顛覆了之前的option寫(xiě)法。
作為當(dāng)年第一波吃vue2螃蟹人,我對(duì)option寫(xiě)法很是喜歡,并且制定了一系列規(guī)范來(lái)寫(xiě)更好的option,如data里面的數(shù)據(jù),按模塊順序、分開(kāi)書(shū)寫(xiě)、vue2 的option屬性需要按順序排列,不能留空(詳見(jiàn):前端規(guī)范 - vue2開(kāi)發(fā)規(guī)范)
在之前的vue2項(xiàng)目中,單vue組件過(guò)大的話,的確會(huì)出現(xiàn)上下橫跳的費(fèi)勁場(chǎng)景,一個(gè)業(yè)務(wù)邏輯需要在data、watch、methods中來(lái)回書(shū)寫(xiě)
使用組合式api的確改變了開(kāi)發(fā)體驗(yàn)。上圖可以很形象的總結(jié)出變化,以后寫(xiě)代碼,單vue組件內(nèi)比較容易劃分模塊
而組合式api代理的所有模塊都是import導(dǎo)入這點(diǎn),與react又是一大相似點(diǎn)
setup語(yǔ)法糖
相對(duì)比第一波吃vue3螃蟹的人,我入場(chǎng)的時(shí)候已經(jīng)支持了setup語(yǔ)法糖,那沒(méi)理由不使用它
組合式函數(shù)來(lái)代替mixin
組合式函數(shù),因?yàn)榕creact hooks的思路類似,業(yè)內(nèi)也叫vue hooks
個(gè)人對(duì)vue2的mixin是又愛(ài)又恨,在拆分巨型vue文件時(shí),mixin往往是利器,但其自身的缺陷(數(shù)據(jù)來(lái)源不明確、數(shù)據(jù)覆蓋等),又讓我不敢隨意使用mixin
組合式函數(shù)的出現(xiàn),就是為了替代mixin;在實(shí)際的開(kāi)發(fā)中,全局、模塊內(nèi)也是創(chuàng)建hooks文件夾,里面放js文件
但hooks也不是100%的好,因?yàn)槠鋫鲄ⅰ⒎祷囟际秋@式定義,因此會(huì)對(duì)上下文順序有依賴
provide、inject來(lái)做全局應(yīng)用
在vue2的時(shí)候,我推薦將http請(qǐng)求、url鏈接統(tǒng)一歸納管理,然后掛載在vue prototype上,就可以直接通過(guò)this進(jìn)行調(diào)用,如下面的代碼
this.$http.get(this.$listUrl.bom.getList, ...)現(xiàn)在就不行了,因?yàn)榻M合式api直接沒(méi)有this了!
替代方案1:每個(gè)界面都引用 $http、$listUrl,這個(gè)屬于下策
替代方案2:在main.ts定義全局變量,然后每個(gè)vue組件通過(guò)getCurrentInstance獲取調(diào)用,如下面代碼
這種跟微信小程序的獲取全局變量很是類似,但是不好用,引用的代碼很多,vue官方也不建議使用
代替防范3:使用provide、inject來(lái)做全局應(yīng)用
在main.js定義全局變量,然后每個(gè)vue組件通過(guò)inject獲取,如下面代碼
雖然不如vue2中使用的便捷,不過(guò)也容易理解
對(duì)vue2代碼的兼容
很多項(xiàng)目無(wú)法升級(jí)到vue3的一大原因是因?yàn)関ue3的周邊生態(tài)不夠完善,尤其是公司內(nèi)部的生態(tài)支持
我這次升級(jí)的業(yè)務(wù)使用到了兩個(gè)復(fù)雜的業(yè)務(wù)組件,直接通過(guò)npm引入是不行的,只能拿到本地來(lái)調(diào)整
vue3也支持之前的option寫(xiě)法,不過(guò)個(gè)別api需要做出改動(dòng),我遇到的改動(dòng)不算很多,具體如下:
- emit需要顯式定義好
- 自定義v-model的改動(dòng)
- 生命周期的改動(dòng)
那些小坑你一把的改動(dòng)
v-model 的改動(dòng),vue2是value,現(xiàn)在是modelValue
prop: value -> modelValue;
event: input -> update:modelValue;
外部調(diào)用組件內(nèi)部方法、屬性,需要顯式拋出
否則調(diào)用不到
// 子組件 // 定義方法 function open() {...} // 顯式拋出 defineExpose({open })那些廢棄了的api
- eventBus 這個(gè)還好,本身算是老古董,我也一直不建議使用
- filter 這個(gè)我很難過(guò),從我接觸vue1.x版本開(kāi)始,過(guò)濾器就是我喜歡vue的一個(gè)特性,現(xiàn)在廢棄了有點(diǎn)舍不得
element plus的升級(jí)
作為vue3的對(duì)應(yīng)版本,能感受到element plus的努力
- icon引入方式的變化 - 這個(gè)影響最大
- size取消了mini的規(guī)格
- button type=“l(fā)ink”的棄用
- treeV2 樹(shù)的虛擬滾動(dòng)添加 - 有小坑需要踩
- tableV2 表格的虛擬滾動(dòng)添加 - 沒(méi)具體使用,估計(jì)也會(huì)有小坑
構(gòu)建工具選擇vite
這算是開(kāi)發(fā)過(guò)程中體驗(yàn)最舒服的地方了,啟動(dòng)秒起、代碼修改后界面秒刷新
默認(rèn)打包命令、文件夾與之前的vue cli默認(rèn)一致,可以無(wú)縫對(duì)接公司的devops系統(tǒng)
不好處:
由于vite使用rollup來(lái)打包,因此你需要做一些配置的話,需要查閱rollup的api文檔,相當(dāng)于你當(dāng)年在webpack踩的坑,現(xiàn)在又需要重新走一遍
Vuex -> Pinia機(jī)會(huì)可以忽略的改動(dòng)
我算是個(gè)vuex的保守使用者,在不需要共享數(shù)據(jù)的時(shí)候,我是不建議使用vuex的
這次項(xiàng)目改動(dòng)使用的Pinia,屬于常規(guī)操作并且地方不多,除了Pinia刪除了mutations這個(gè)小改動(dòng)外,沒(méi)感覺(jué)到有多大的變化
cdn的引入
vite是支持靜態(tài)js通過(guò)cdn來(lái)引用的,這樣會(huì)減少加載包的大小
社區(qū)有很多解決方案,都是通過(guò)rollup的擴(kuò)展能力
不過(guò)我使用cdn引入,與微前端的模式有沖突,后面放棄了cdn的引用
微前端的適配
一早就知道qiankun的官網(wǎng)不支持vite,但又舍不得vite的開(kāi)發(fā)體驗(yàn),一開(kāi)始想做成本地vite+打包使用webpack的模式,
不過(guò)還是在社區(qū)里面找到了解決方案,通過(guò)vite-plugin-qiankun來(lái)實(shí)現(xiàn),雖然最后無(wú)法實(shí)現(xiàn)動(dòng)態(tài)插入publicPath,不過(guò)瑕不掩瑜,完全不影響生產(chǎn)環(huán)境使用
其他開(kāi)發(fā)體驗(yàn)
- 使用proxy代替了Object.defineProperty做數(shù)據(jù)綁定這點(diǎn),對(duì)開(kāi)發(fā)體驗(yàn)小有提升,不需要再寫(xiě)$set、數(shù)組splice模擬通過(guò)下標(biāo)修改
- Volar不是那么的好用,無(wú)法進(jìn)行詳細(xì)的配置,格式化的時(shí)候?qū)M件多屬性的折疊不友好,這里推薦使用prettier做代碼格式化;而且
- vsode開(kāi)發(fā)體驗(yàn),不知是個(gè)人vscode的問(wèn)題,感覺(jué)代碼提示、輸入反饋,不如vue2項(xiàng)目的體驗(yàn)來(lái)的好,后續(xù)需要持續(xù)關(guān)注
- vue devtools升級(jí)到了新版本,體驗(yàn)倒是不錯(cuò)
性能提升
說(shuō)實(shí)話,由于數(shù)據(jù)量不是十分大,直觀體驗(yàn)上,性能沒(méi)有多少提升……后續(xù)需要找一下經(jīng)典場(chǎng)景來(lái)測(cè)試一下
總結(jié)
這個(gè)項(xiàng)目也算是完整的從0到1開(kāi)發(fā)一個(gè)vue3項(xiàng)目,雖然項(xiàng)目不算大,但麻雀雖小五臟俱全,該有的體驗(yàn)也都把玩了一下。
總體來(lái)說(shuō),vue3帶來(lái)了一些新內(nèi)容,但還是屬于框架內(nèi)的改動(dòng),無(wú)法影響到整個(gè)前端圈。如果是之前平穩(wěn)運(yùn)行的項(xiàng)目,不建議推倒重構(gòu)
到vue3版本,新項(xiàng)目或者小項(xiàng)目重構(gòu),可以大膽使用vue3
vue3是vue的未來(lái),現(xiàn)在也已經(jīng)很成熟了,后續(xù)的新項(xiàng)目,都推薦使用vue3來(lái)做的
后續(xù)
近期需要根據(jù)此項(xiàng)目,抽出腳手架來(lái),供團(tuán)隊(duì)內(nèi)使用。
還需要多學(xué)習(xí)總結(jié),打造vue3版本的代碼規(guī)范+最佳實(shí)踐,以及ts的代碼規(guī)范
總結(jié)
以上是生活随笔為你收集整理的vue3开发实践总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 网上书店订单流程c语言源代码,网上书店的
- 下一篇: 好人卢安克之感想