1串远、vue3.0和2.0的區(qū)別
Vue3.0正式發(fā)布后,我在各大視頻教學(xué)平臺(tái)和技術(shù)論壇里看了下評(píng)論,有開(kāi)發(fā)者反饋其兼容性不是很好蒙袍,同時(shí)在命令方面也有不少變化,總體使用情況不是特別的樂(lè)觀嫩挤。
vue3.0 的發(fā)布與 vue2.0 相比害幅,優(yōu)勢(shì)主要體現(xiàn)在:更快、更小岂昭、更易維護(hù)以现、更易于原生、讓開(kāi)發(fā)者更輕松约啊;
更快:
1邑遏、virtual DOM 完全重寫(xiě),mounting & patching 提速 100%恰矩;
2记盒、更多編譯時(shí) (compile-time)提醒以減少 runtime 開(kāi)銷;
3外傅、基于 Proxy 觀察者機(jī)制以滿足全語(yǔ)言覆蓋以及更好的性能纪吮;
4、放棄 Object.defineProperty 萎胰,使用更快的原生 Proxy碾盟;
5、組件實(shí)例初始化速度提高 100%;
6技竟、提速一倍/內(nèi)存使用降低一半冰肴;
更小:
1灵奖、Tree-shaking 更友好嚼沿;
2、新的 core runtime:~ 10kb gzipped瓷患;
vue3.0 新加入了 TypeScript 以及 PWA 的支持
2骡尽、部分命令發(fā)生了變化:
(1)下載安裝 npm install -g vue@cli
(2)刪除了vue list
(3)創(chuàng)建項(xiàng)目 vue create
(4)啟動(dòng)項(xiàng)目 npm run serve
3、默認(rèn)項(xiàng)目目錄結(jié)構(gòu)也發(fā)生了變化:
(1)移除了配置文件目錄擅编,config 和 build 文件夾
(2)移除了 static 文件夾攀细,新增 public 文件夾箫踩,并且 index.html 移動(dòng)到 public 中
(3)在 src 文件夾中新增了 views 文件夾,用于分類 視圖組件 和 公共組件
4谭贪、在創(chuàng)建和啟動(dòng)方面:
創(chuàng)建文件方面:
3.0:vue create 進(jìn)入工程文件夾境钟,創(chuàng)建項(xiàng)目。
2.0:vue init webpack
啟動(dòng)項(xiàng)目方面:
3.0啟動(dòng)npm run serve
2.0啟動(dòng)npm run dev
其中俭识,build沒(méi)了慨削、config沒(méi)了、哦對(duì)了還有最重要的一點(diǎn)套媚,3.0的安裝項(xiàng)目時(shí)自動(dòng)下載node-model缚态。
在根目錄下創(chuàng)建一個(gè)vue.config.js
module.exports = {
baseUrl: process.env.NODE_ENV === 'production' ? '/online/' : '/',
// outputDir: 在npm run build時(shí) 生成文件的目錄 type:string, default:'dist'
// outputDir: 'dist',
// pages:{ type:Object,Default:undfind }
devServer: {
port: 8888, // 端口號(hào)
host: 'localhost',
https: false, // https:{type:Boolean}
open: true, //配置自動(dòng)啟動(dòng)瀏覽器
// proxy: 'http://localhost:4000' // 配置跨域處理,只有一個(gè)代理
proxy: {
'/api': {
target: '<url>',
ws: true,
changeOrigin: true
},
'/foo': {
target: '<other_url>'
}
}, // 配置多個(gè)代理
}
}
5、此外堤瘤,Vue3.0和Vue2.0還有以下區(qū)別:
一玫芦、默認(rèn)進(jìn)行懶觀察(lazy observation)。
在 2.x 版本里本辐,不管數(shù)據(jù)多大桥帆,都會(huì)在一開(kāi)始就為其創(chuàng)建觀察者。當(dāng)數(shù)據(jù)很大時(shí)慎皱,這可能會(huì)在頁(yè)面載入時(shí)造成明顯的性能壓力老虫。3.x 版本,只會(huì)對(duì)「被用于渲染初始可見(jiàn)部分的數(shù)據(jù)」創(chuàng)建觀察者茫多,而且 3.x 的觀察者更高效张遭。
描述的再通俗、再清晰一點(diǎn)就是:
1地梨、對(duì)于diff算法的優(yōu)化菊卷。
在vue2中,虛擬dom是全量比較的宝剖。
在vue3中洁闰,增加了靜態(tài)標(biāo)記PatchFlag。
在創(chuàng)建vnode的時(shí)候万细,會(huì)根據(jù)vnode的內(nèi)容是否可以變化扑眉,為其添加靜態(tài)標(biāo)記PatchFlag。diff的時(shí)候赖钞,只會(huì)比較有PatchFlag的節(jié)點(diǎn)腰素。PatchFlag是有類型的,比如一個(gè)可變化文本節(jié)點(diǎn)雪营,會(huì)將其添加PatchFlag枚舉值為T(mén)EXT的靜態(tài)標(biāo)記弓千。這樣在diff的時(shí)候,只需比對(duì)文本內(nèi)容献起。需要比對(duì)的內(nèi)容更少了洋访。PatchFlag還有動(dòng)態(tài)class镣陕、動(dòng)態(tài)style、動(dòng)態(tài)屬性姻政、動(dòng)態(tài)key屬性等枚舉值呆抑。
2、render階段的靜態(tài)提升(render階段指生成虛擬dom樹(shù)的階段)
在vue2中汁展,一旦檢查到數(shù)據(jù)變化鹊碍,就會(huì)re-render組件,所有的vnode都會(huì)重新創(chuàng)建一遍食绿,形成新的vdom樹(shù)妹萨。
在vue3中,對(duì)于不參與更新的vnode炫欺,會(huì)做靜態(tài)提升,只會(huì)被創(chuàng)建一次熏兄,在re-render時(shí)直接復(fù)用品洛。
靜態(tài)提升可以理解為第一次render不參與更新的vnode節(jié)點(diǎn)的時(shí)候,保存它們的引用摩桶。re-render新vdom樹(shù)時(shí)桥状,直接拿它們的引用過(guò)來(lái)即可,無(wú)需重新創(chuàng)建硝清。
3辅斟、事件偵聽(tīng)緩存
在vue2中,我們寫(xiě)的@click="onClick"也是被當(dāng)作動(dòng)態(tài)屬性芦拿,diff的時(shí)候也要對(duì)比士飒。但我們知道它不會(huì)變化,比如變成@click="onClick2"蔗崎,綁定別的值酵幕。
在vue3中,如果事件是不會(huì)變化的缓苛,會(huì)將onClick緩存起來(lái)(跟靜態(tài)提升達(dá)到的效果類似)芳撒,該節(jié)點(diǎn)也不會(huì)被標(biāo)記上PatchFlag(也就是無(wú)需更新的節(jié)點(diǎn))。這樣在render和diff兩個(gè)階段未桥,事件偵聽(tīng)屬性都節(jié)約了不必要的性能消耗笔刹。
我曾經(jīng)維護(hù)過(guò)一個(gè)擁有很龐大dom樹(shù)的頁(yè)面。由于節(jié)點(diǎn)非常多冬耿,無(wú)需參與更新的節(jié)點(diǎn)也很多舌菜,使用vue2的情況下,在render和diff兩個(gè)階段亦镶,消費(fèi)了很多性能酷师,如果當(dāng)時(shí)有vue3的話讶凉,我想性能會(huì)被優(yōu)化很多。
4山孔、減少創(chuàng)建組件實(shí)例的開(kāi)銷
vue2.x每創(chuàng)建一個(gè)實(shí)例懂讯,在this上要暴露data、props台颠、computed這些褐望,都是靠Object.defineProperty去定義的。這部分操作還是挺費(fèi)時(shí)的串前。
vue3.0中基于Proxy瘫里,減少了創(chuàng)建組件實(shí)例的性能開(kāi)銷。
二荡碾、更精準(zhǔn)的變更通知
比例來(lái)說(shuō):2.x 版本中谨读,你使用 Vue.set 來(lái)給對(duì)象新增一個(gè)屬性時(shí),這個(gè)對(duì)象的所有 watcher 都會(huì)重新運(yùn)行坛吁;3.x 版本中劳殖,只有依賴那個(gè)屬性的 watcher 才會(huì)重新運(yùn)行。
三拨脉、3.0 新加入了 TypeScript 以及 PWA 的支持哆姻。
vue2不適合使用ts,原因在于vue2的Option API風(fēng)格玫膀。options是個(gè)簡(jiǎn)單對(duì)象矛缨,而ts是一種類型系統(tǒng)、面向?qū)ο蟮恼Z(yǔ)法帖旨。兩者有點(diǎn)不匹配箕昭。
在vue2結(jié)合ts的具體實(shí)踐中,要用 vue-class-component 強(qiáng)化 vue 組件解阅,讓 Script 支持 TypeScript 裝飾器盟广,用 vue-property-decorator 來(lái)增加更多結(jié)合 Vue 特性的裝飾器,最終搞的ts的組件寫(xiě)法和js的組件寫(xiě)法差別挺大瓮钥。
在vue3中筋量,量身打造了defineComponent函數(shù),使組件在ts下碉熄,更好的利用參數(shù)類型推斷 桨武。Composition API 代碼風(fēng)格中,比較有代表性的api就是 ref 和 reactive锈津,也很好的支持了類型聲明呀酸。
四、部分命令發(fā)生了變化:
下載安裝 npm install -g vue@cli
刪除了vue list
創(chuàng)建項(xiàng)目 vue create
啟動(dòng)項(xiàng)目 npm run serve
同時(shí)琼梆,vue3.0使用 vite開(kāi)發(fā)構(gòu)建工具 可以有更快的開(kāi)發(fā)體驗(yàn) 性誉。
在使用webpack作為開(kāi)發(fā)構(gòu)建工具時(shí)窿吩,npm run dev都要等一會(huì),項(xiàng)目越大等的時(shí)間越長(zhǎng)错览。熱重載頁(yè)有幾秒的延遲纫雁,但是如果用vite來(lái)做vue3的開(kāi)發(fā)構(gòu)建工具,npm run dev 秒開(kāi)倾哺,熱重載也很快轧邪。
vite的原理還是用了瀏覽器支持import關(guān)鍵字了,啟動(dòng)項(xiàng)目不用webpack構(gòu)建工具先構(gòu)建了羞海,瀏覽器直接請(qǐng)求路由對(duì)應(yīng)的代碼文件忌愚,代理服務(wù)器針對(duì)單個(gè)文件進(jìn)行編譯并返回。如果請(qǐng)求的文件里還import了其他文件却邓,同理瀏覽器繼續(xù)發(fā)請(qǐng)求硕糊,代理服務(wù)器返回。就這樣實(shí)現(xiàn)了npm run dev時(shí)無(wú)需編譯腊徙,實(shí)時(shí)請(qǐng)求實(shí)時(shí)編譯简十。
五、默認(rèn)項(xiàng)目目錄結(jié)構(gòu)也發(fā)生了變化:
移除了配置文件目錄昧穿,config 和 build 文件夾。
移除了 static 文件夾橙喘,新增 public 文件夾时鸵,并且 index.html 移動(dòng)到 public 中。
在 src 文件夾中新增了 views 文件夾厅瞎,用于分類 視圖組件 和 公共組件饰潜。
總結(jié):
其他的,數(shù)據(jù)監(jiān)聽(tīng)方式變成了Proxy和簸,消除了Object.defineProperty現(xiàn)有的限制(例如無(wú)法檢測(cè)新的屬性添加)彭雾,并提供更好的性能。
vue3解決了vue2的一些問(wèn)題锁保,大型應(yīng)用的性能問(wèn)題薯酝、ts支持不友好問(wèn)題,自定義渲染API解決體系架構(gòu)存在的問(wèn)題爽柒,如果在vue3的基礎(chǔ)上實(shí)現(xiàn)weex框架會(huì)好很多吴菠。也做出了很多優(yōu)化,Compostion API讓代碼的組織形式更好浩村。vite開(kāi)發(fā)構(gòu)建工具讓開(kāi)發(fā)體驗(yàn)更好做葵,Tree shaking讓包更小、性能更優(yōu)心墅。