Vue3 + Vite2 項(xiàng)目實(shí)戰(zhàn)復(fù)盤總結(jié)(干貨!)
——————— ? Y ?· ?F ?· ?E ? ———————

內(nèi)容概要
?背景?vue3 項(xiàng)目開發(fā) get 到的知識(shí)?讓我驚訝的 vite?項(xiàng)目中遇到的困難?總結(jié)?項(xiàng)目技術(shù)棧?資料推薦
背景
有一個(gè)新項(xiàng)目啟動(dòng),移動(dòng)端項(xiàng)目兼容安卓 6+,沒有歷史包袱,技術(shù)選型可以自由發(fā)揮。考慮到項(xiàng)目周期/團(tuán)隊(duì)技術(shù)/學(xué)習(xí)成本,最后選取還算比較新的 vue3。
不過等我的項(xiàng)目上線到寫完這篇,有些東西已經(jīng)不是最新的啦,Vue 3.1.0 的 beta 版發(fā)布了不得不感慨前端技術(shù)日新月異,變化的速度之快,我學(xué)不動(dòng)了。
vue3 項(xiàng)目開發(fā) get 到的知識(shí)
剛開始用的時(shí)候,可懷念 vue2 了,我始終 get 不到 vue3 的精華,也理解不了網(wǎng)上說的組合式API 有多好。vue2 我是輕車熟路,vue3 我是面向文檔開發(fā)。選擇了用 vue3,就要去 get 他的精華,用著用著我發(fā)現(xiàn)真香,vue3 和 vite2 結(jié)合的項(xiàng)目驚訝到我了。
組合式 API 解決了什么問題?
在開始寫項(xiàng)目的時(shí)候,我一直沒有 get 到組合 API 的有優(yōu)點(diǎn),還沒有了全局的 this,我就有點(diǎn)不開心了,但是隨著項(xiàng)目越來越復(fù)雜,頁面越來越大的時(shí)候我就發(fā)現(xiàn)組合 API 真香。特別喜歡。
vue2 數(shù)據(jù)定義在 data,方法在 method,中間可能還有 watch,computed 等等別的東西,數(shù)據(jù)定義和方法處理邏輯之間差了十萬八千里,當(dāng)邏輯復(fù)雜達(dá)到一定長度的時(shí)候,追蹤一個(gè)變量的變化是一件非常頭痛的事情,鼠標(biāo)需要來回滾動(dòng)。

有了組合 API,這個(gè)問題就解決了。所有相關(guān)的都可以寫在一塊。真好,它帶來了一種全新的開發(fā)方式。如果你是 React 開發(fā)用戶或者熟悉 React,那么 vue3 上手很快,你甚至都可以在頁面中使用 hooks 的方式開發(fā)。由于這個(gè)項(xiàng)目使用場景比較小,所以在項(xiàng)目中并沒有進(jìn)行采用 hooks 的方式,后續(xù)有需要的時(shí)候可以考慮使用。了解更多關(guān)于組合式 API 請(qǐng)參考文檔什么是組合式 API?[1]
API的變化

由于在執(zhí)行 setup 時(shí),組件實(shí)例尚未被創(chuàng)建,因此在 setup 選項(xiàng)中沒有 this。這意味著,除了 props 之外,你將無法訪問組件中聲明的任何屬性——本地狀態(tài)、計(jì)算屬性或方法。setup 選項(xiàng)應(yīng)該是一個(gè)接受 props 和 context 的函數(shù)。
因?yàn)?props 是響應(yīng)式的,你不能使用 ES6 解構(gòu),因?yàn)樗鼤?huì)消除 prop 的響應(yīng)性。如果需要解構(gòu)需要用 toRefs。
執(zhí)行 setup 時(shí),組件實(shí)例尚未被創(chuàng)建。因此,你只能訪問以下 property:
propsattrsslotsemit
換句話說,你將無法訪問以下組件選項(xiàng):
datacomputedmethods
整個(gè)項(xiàng)目下來與 vue2 只有語法的差別,思想啥的變化不大,不難。面向文檔開發(fā)基本可以滿足你的需求。
一個(gè)組件的思考
如何寫好一個(gè)組件,組件的規(guī)劃/使用/維護(hù),始終是一個(gè)值得深入思考的問題。Composition API 帶了了一種全新的開發(fā)方式,甚至可以使用 hooks 的方式開發(fā)。每個(gè)模塊各司其職,各自有自己的內(nèi)部數(shù)據(jù),公共的使用函數(shù)或者 hooks 抽象出來,整體上非常清爽,工程化越來越強(qiáng),在項(xiàng)目中開發(fā)是否全部要使用 .vue 創(chuàng)建組件呢?
以前我覺得既然我選了 vue,就要用 .vue 的形式,但是在這次的項(xiàng)目開發(fā)過程中,我看到了我的小伙伴使用了原生 js 創(chuàng)建組件,我眼前一亮,在某些情況下用原生的 js 創(chuàng)建組件是一個(gè)非常不錯(cuò)的選擇,那一刻我明白了,適合自己實(shí)際需求的才是最好的,混合式組件開發(fā)可以取長補(bǔ)短。
比如接口請(qǐng)求過程中,用戶突然斷網(wǎng)了,前端提示用戶斷網(wǎng)的頁面,這代碼就很簡潔了。

還有用 jsx 方式創(chuàng)建的組件,可定制化。

適當(dāng)?shù)倪壿孅c(diǎn)分離: 埋點(diǎn)邏輯和業(yè)務(wù)邏輯分離更加有益于項(xiàng)目后期的維護(hù)(自定義指令實(shí)現(xiàn)聲明式埋點(diǎn))。

路由邏輯的處理

視野中出現(xiàn)了焦點(diǎn),也就出現(xiàn)了盲點(diǎn)。路由邏輯處理這塊,我就坑到自己了,我焦點(diǎn)都在組合式API,在組合式 API 文檔我找不到進(jìn)入路由時(shí)候的生命周期函數(shù)。結(jié)果就導(dǎo)致我部分頁面邏輯寫在了 router.js 里面。
// 路由文件{path:?'/index',component: HOME,??beforeEnter:?(to,?from)?=>?{if (from.path === "/read") {to.meta = {updateHistory: 'read',}}}};// 頁面文件watch(() => route.meta,(val) => {??if?(val.updateHistory)?{getHistoryHandler()}});
這是一個(gè)非常非常不好的寫法,頁面邏輯和路由邏輯耦合在一起,后期維護(hù)帶來了很大的問題,后來同事指點(diǎn),糾正了這個(gè)問題。我竟然忽略了它原來的語法,去執(zhí)著與他的新語法。

所有頁面需要統(tǒng)一的動(dòng)態(tài)的一級(jí)路由前綴,即路由的一級(jí)域名不是由前端控制的,但是在實(shí)際開發(fā)中,前端路由規(guī)則是要關(guān)注一級(jí)路由的。按照一貫的邏輯是所有的路由配置動(dòng)態(tài)路由即path: '/:flag/index', path: '/:flag/listen'....只要是有路由就需要在前面加上/:flag,某些情況下還需要處理在業(yè)務(wù)邏輯里面單獨(dú)處理,這個(gè)邏輯混在比較多,不利于后期的維護(hù)。
想偷懶,思考有沒有簡單的解決方法,同事一番研究花了不少時(shí)間,不斷試錯(cuò)不斷研究,終于發(fā)現(xiàn)可在路由上面做文章,一句代碼解決了大量重復(fù)的勞力。簡直開心的不能再開心,分分鐘搞定了createWebHistory 支持設(shè)置base文件目錄[2]
createWebHistory(location.pathname.split('/')[1])
原來打包的時(shí)候還能動(dòng)態(tài)的指定路由方式,真棒。
讓我驚訝的 vite
開發(fā)體驗(yàn)對(duì)比
項(xiàng)目啟動(dòng)&&項(xiàng)目打包&&項(xiàng)目體積


ps:由于 vue-cli 和 vite 的環(huán)境變量讀取方式和某一些 css 的引入方式不一樣,在 vue-cli 里面我就注釋了相關(guān)的代碼。確保項(xiàng)目能夠跑去來。除此之外別的幾乎是一模一樣
通過數(shù)據(jù)對(duì)比可見:
vite 創(chuàng)建的項(xiàng)目,在項(xiàng)目啟動(dòng)和打包后的體積方面都遠(yuǎn)遠(yuǎn)勝過 vue-cli 創(chuàng)建的項(xiàng)目。
vue-cli 創(chuàng)建的項(xiàng)目,打包速度優(yōu)于vite一點(diǎn),但是在我們開發(fā)過程中,經(jīng)常打包頻率并不高,而且慢的也沒有很夸張離譜。
就我個(gè)人而言,我更加傾向于 vite 去搭建項(xiàng)目。
vite 是如何吸引我的?
1.無邊界 => 純 html 項(xiàng)目,react 項(xiàng)目都可以,項(xiàng)目中可以使用較新的語法,兼容性交給工具。

1.緊跟時(shí)代的語法潮流支持
module 形式引入 js 腳本
在 js 里面,可以通過這種形式引入 css
支持 css 模塊化寫法 純 html 項(xiàng)目也可以做到實(shí)時(shí)更新
讓我們可以只需要關(guān)注業(yè)務(wù)開發(fā),而無需去關(guān)注語法層面的兼容性以及打包配置,我喜歡這樣的開發(fā)體驗(yàn)。
vite demo 代碼地址[3]
項(xiàng)目遇到的困難
困難總比辦法多,再多的問題都會(huì)慢慢被解決,項(xiàng)目會(huì)如期上線。項(xiàng)目的開發(fā),磕磕碰碰,才有成長,學(xué)到東西才有意義。
輪播組件
應(yīng)產(chǎn)品需求,輪播組件最終使用第三方插件,最初選用 vue-awesome-swiper ,但是 vue3 不支持,雖然官方有 vue3 的 demo,但是需要 vue2與 vue3 混用。

一番查找最后選用 swiper 插件,本身就支持了 vue3 ,而且他只支持 vue3,救了我。

就是文檔寫的不太好,很多并沒有明確的暴露出來,需要去 swiper.js 文檔查找, swiper 本身支持現(xiàn)在主流的框架這是一個(gè)很棒的體驗(yàn),就是文檔這一塊需要加油。
虛擬滾動(dòng)
頁面列表加載上百千條數(shù)據(jù)時(shí),白屏?xí)r間長,滾動(dòng)有卡頓。最開始考慮采用前端頁面分頁,只要數(shù)據(jù)夠多頁面 dom 節(jié)點(diǎn)還是很多,達(dá)到一定量卡頓依舊存在。后來使用 vue-virtual-scroller 解決問題,但在網(wǎng)上看到大部分都是vue2版本的,vue3 版本都是在 issues 里面找到的。

在使用過程中又遇到,缺少某些方法導(dǎo)致無法滿足產(chǎn)品需求,最后源碼查找到滿足需求的方法。vue3 本身的文檔也不夠完善,如果能夠暴露更多的方法,而不是源碼找,體驗(yàn)會(huì)更好。

但是這個(gè)項(xiàng)目在 github 上面的 star 很不錯(cuò),應(yīng)該是靠譜的,只是人家還沒來得及做吧,哈哈。

總結(jié)
以上就我個(gè)人這次項(xiàng)目實(shí)戰(zhàn)的經(jīng)驗(yàn)而言,在用新的 API 的時(shí)候,需要思考一個(gè)問題,邏輯點(diǎn)聚合,同時(shí)也要注意轉(zhuǎn)變代碼組織思維。這不僅是 vue2 和 vue3 的區(qū)別,而是一直以來我們應(yīng)該思考的一個(gè)問題,每次開發(fā)都應(yīng)該思考,如何能讓這個(gè)項(xiàng)目/組件能夠長期穩(wěn)定的發(fā)展。框架的更新于用戶而言不僅僅是語法的更新,而應(yīng)該去思考,框架在發(fā)展中遇到了什么問題?他是如何解決的?為了我們開發(fā)的項(xiàng)目長期穩(wěn)定可持續(xù)的發(fā)展,是否可以借鑒他們的經(jīng)驗(yàn)?
項(xiàng)目中使用到的技術(shù)棧及文檔
vite.config 的配置文檔?[4]
路由 router[5]
vue3[6]
輪播插件swiper[7]
虛擬滾動(dòng)vue3 版本[8]
vue3/vite資料推薦
昨晚尤大的連麥直播,我學(xué)到了很多!!![9]
vite 文檔[10]
備戰(zhàn)2021:vite工程化實(shí)踐,建議收藏[11]
手?jǐn)]Vite,揭開Vite神秘面紗[12]
備戰(zhàn)2021:Vite2項(xiàng)目最佳實(shí)踐[13]
【譯】下一代前端構(gòu)建工具 ViteJS 中英雙語字幕 | 技術(shù)點(diǎn)評(píng)[14]
【譯】下一代前端工具 ViteJS 中英雙語字幕 - Open Source Friday[15]
忙了一夜用CompositionAPI征服產(chǎn)品妹子花里胡哨的需求[16]
閃電五連鞭:Composition API原理深度剖析[17]
vue3 源碼解析[19]
References
[1]?什么是組合式 API?:?https://v3.cn.vuejs.org/guide/composition-api-introduction.html#%E4%BB%80%E4%B9%88%E6%98%AF%E7%BB%84%E5%90%88%E5%BC%8F-api[2]?createWebHistory 支持設(shè)置base文件目錄:?https://next.router.vuejs.org/zh/api/#createwebhistory?fileGuid=t3GvJVRGxRkXgypy[3]?vite demo 代碼地址:?https://github.com/sunseekers/vite/blob/main/index.html[4]?vite.config 的配置文檔 :?https://cn.vitejs.dev/config/#mode[5]?路由 router:?https://next.router.vuejs.org/introduction.html[6]?vue3:?https://v3.cn.vuejs.org/guide/installation.html#%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%B7%A5%E5%85%B7-cli[7]?輪播插件swiper:?https://swiperjs.com/vue[8]?虛擬滾動(dòng)vue3 版本:?https://github.com/Akryum/vue-virtual-scroller/blob/next/packages/vue-virtual-scroller/README.md[9]?昨晚尤大的連麥直播,我學(xué)到了很多!!!:?https://juejin.cn/post/6960506633839443981#comment[10]?vite 文檔:?https://cn.vitejs.dev/guide/why.html[11]?備戰(zhàn)2021:vite工程化實(shí)踐,建議收藏:?https://juejin.cn/post/6910014283707318279[12]?手?jǐn)]Vite,揭開Vite神秘面紗:?https://juejin.cn/post/6960110425438421006[13]?備戰(zhàn)2021:Vite2項(xiàng)目最佳實(shí)踐:?https://juejin.cn/post/6924912613750996999[14]?【譯】下一代前端構(gòu)建工具 ViteJS 中英雙語字幕 | 技術(shù)點(diǎn)評(píng):?https://juejin.cn/post/6937176680251424775[15]?【譯】下一代前端工具 ViteJS 中英雙語字幕 - Open Source Friday:?https://www.bilibili.com/video/BV1kh411Q7WN[16]?忙了一夜用CompositionAPI征服產(chǎn)品妹子花里胡哨的需求:?https://juejin.cn/post/6891885484524437518[17]?閃電五連鞭:Composition API原理深度剖析:?https://juejin.cn/post/6894993303486332941[18]?不要再用 vue2 思想寫 vue3 了:?https://mp.weixin.qq.com/s/w4n_WhbDqK4kgzxEHUWWfw[19]?vue3 源碼解析:?https://vue3js.cn/reactivity/reactive.spec.html
?
——————— ? Y ?· ?F ?· ?E ? ———————
???本文作者:閱文前端團(tuán)隊(duì)
轉(zhuǎn)載請(qǐng)向閱文前端團(tuán)隊(duì)微信公眾號(hào)(id:yuewen_YFE)獲取授權(quán),并注明作者、出處和鏈接
歡迎大家關(guān)注我們掘金和知乎分享賬戶:閱文前端團(tuán)隊(duì)

