記一次 Vue2 遷移 Vue3 的實踐總結

大家好,我是若川。持續組織了6個月源碼共讀活動,感興趣的可以點此加我微信 ruochuan12?參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》?包含20余篇源碼文章。歷史面試系列

一、Vue3

Vue3中文文檔[1]

  • Vue3是什么,與Vue2區別(What)

  1. Performance:性能更強。

  2. Tree shaking support:可以將無用模塊“剪輯”,僅打包需要的。

  3. Composition API:組合式API

  4. Fragment, Teleport, Suspense:“碎片”,TeleportProtal傳送門,“懸念”

  5. Better TypeScript support:更優秀的Ts支持

  6. Custom Renderer API:暴露了自定義渲染API

  • 為什么要大版本迭代 (Why)

  1. 主流瀏覽器對新的JavaScript語言特性的普遍支持。

  2. 當前Vue代碼庫隨著時間的推移而暴露出來的設計和體系架構問題。

  • 他是如何提升的(How)

  1. 響應式系統提升: 使用Proxy提升了響應式的性能和功能

  2. 編譯優化: 標記和提升所有的靜態節點,diff時只需要對比動態節點內容

  3. 事件緩存: 提供了事件緩存對象cacheHandlers,無需重新創建函數直接調用緩存的事件回調

  4. 打包和體積優化: 按需引入,Tree shaking支持(ES Module)

二、編碼

全局API

  1. 新增】createApp: 入口文件(main.ts)掛載方式

import?{?createApp?}?from?"vue";import?App?from?"./App.vue";//?Vue2new?Vue({render:?(h)?=>?h(App)}).$mount("#app");//?Vue3createApp(App).use(**).mount("#app");
  1. 【修改】

2.x 全局 API3.x 實例 API (app)
Vue.configapp.config
Vue.config.productionTip
Vue.config.ignoredElementsapp.config.isCustomElement
Vue.componentapp.component
Vue.directiveapp.directive
Vue.mixinapp.mixin
Vue.useapp.use
Vue.prototypeapp.config.globalProperties

config.ignoredElements替換為config.isCustomElement

引入此配置選項的目的是支持原生自定義元素,因此重命名可以更好地傳達它的功能,新選項還需要一個比舊的 string/RegExp 方法提供更多靈活性的函數:

//?Vue2Vue.config.ignoredElements?=?[//?用一個?`RegExp`?忽略所有“ion-”開頭的元素//?僅在?2.5+?支持/^ion-/]//?Vue3const?app?=?Vue.createApp({})app.config.isCustomElement?=?tag?=>?tag.startsWith('ion-')

Vue.prototype 替換為 config.globalProperties

在Vue 2中,Vue.prototype通常用于添加可在所有組件中訪問的屬性。

Vue 3中的等效項是config.globalProperties。在實例化應用程序內的組件時,將復制這些屬性

//?Vue2Vue.prototype.$http?=?()?=>?{}//?Vue3const?app?=?Vue.createApp({})app.config.globalProperties.$http?=?()?=>?{}

生命周期

2.0生命周期3.0生命周期
beforeCreate(組件創建之前)setup()
created(組件創建完成)setup()
beforeMount(組件掛載之前)onBeforeMount(組件掛載之前)
mounted(組件掛載完成)onMounted(組件掛載完成)
beforeUpdate(數據更新,虛擬DOM打補丁之前)onBeforeUpdate(數據更新,虛擬DOM打補丁之前)
updated(數據更新,虛擬DOM渲染完成)onUpdated(數據更新,虛擬DOM渲染完成)
beforeDestroy(組件銷毀之前)onBeforeUnmount(組件銷毀之前)
destroyed(組件銷毀之后)onUnmounted(組件銷毀之后)
activated(被 keep-alive 緩存的組件激活時調用)onActivated(被激活時執行)
deactivated(被 keep-alive 緩存的組件停用時調用)onDeactivated(比如從 A 組件,切換到 B 組件,A 組件消失時執行)
errorCaptured(當捕獲一個來自子孫組件的錯誤時被調用)onErrorCaptured(當捕獲一個來自子孫組件的異常時激活鉤子函數)

新特性

  1. Options API => Composition API

2bd0bbfef0b153dbac77359962e78b1e.gifef8ac0c95101993c2f7519a9772d24a3.gif
  1. setup()

import?{toRefs}?from?'vue'export?default?{name:?'demo',props:{name:?String,},// setup()作為在組件內使用Composition API的入口點。//?執行時機是在beforeCreate和created之間,不能使用this獲取組件的其他變量,//?而且不能是異步。setup返回的對象和方法,都可以在模版中使用。setup(props,?context){//?這里需要使用toRefs來進行解構//?這里的props與vue2基本一致,當然這里的name也可以直接在template中使用const?{?name?}=toRefs(props);console.log(name.value);//?context是一個上下文對象//【從原來?2.x?中?this?選擇性地暴露了一些?property(attrs/emit/slots)】//?屬性,同vue2的?$attrsconsole.log(context.attrs);//?插槽console.log(context.slots);//?事件,同vue2的?$emitconsole.log(context.emit);//?生命周期鉤子onMounted(()?=>?{})}}

注意點:

  • 注意 props 對象是響應式的,watchEffectwatch 會觀察和響應 props 的更新,不要解構 props 對象,那樣會使其失去響應性

  • attrsslots 都是內部組件實例上對應項的代理,可以確保在更新后仍然是最新值。所以可以解構,無需擔心后面訪問到過期的值

  • this setup()中不可用。由于 setup() 在解析 2.x 選項前被調用,setup() 中的 this 將與 2.x 選項中的 this 完全不同。同時在 setup() 和 2.x 選項中使用 this 時將造成混亂

  1. 響應式reactive,ref

import?{?ref,?reactive,?toRefs?}?from?'vue';setup()?{//?ref//?ref?對我們的值創建了一個響應式引用const?counter?=?ref(0);?//?reactive//?接收一個普通對象然后返回該普通對象的響應式代理const?obj?=?{a:1};const?objReactive?=?reactive(obj);const?add?=?()?=>?{counter.value++;objReactive.a++;}return?{counter,??//?return返回會自動解套【在模板中不需要.value】objReactive,add,};?//?這里返回的任何內容都可以用于組件的其余部分}


refreactive
入參基本類型引用類型
返回值響應式且可變的 ref 對象響應式代理(Proxy)
訪問方式1.ref 對象擁有一個指向內部值的單一屬性 .value
2.在dom和setup()的return中會自動解套
3.ref 作為 reactive 對象的 property 被訪問或修改時,也將自動解套
直接.訪問即可

問題 & 注意點: 因為reactive是組合函數【對象】,所以必須始終保持對這個所返回對象的引用以保持響應性,不能解構該對象或者展開

例如:

const { a } = objReactive或者return { ...objReactive }

解決方法:

toRefs API

用來提供解決此約束的辦法——它將響應式對象的每個 property 都轉成了相應的 ref【把對象轉成了ref】。

import?{?reactive,?toRefs?}?from?'vue';setup()?{//?reactive//?接收一個普通對象然后返回該普通對象的響應式代理const?obj?=?{a:1};const?objReactive?=?reactive(obj);//?toRefs//?將響應式對象轉換為普通對象,其中結果對象的每個?property?都是指向原始對象相應?property?的refconst?objRef?=?toRefs(objReactive);const?{?a?}?=?objRef;const?addObj?=?()?=>?{a.value++;console.log(a.value,?objRef,?objReactive,?obj);}return?{...objRef,addObj};?}
  • Hooks方式

  1. counter.js

import?{?ref?}?from?'vue';export?function?useCounter()?{const?count?=?ref(0);const?decrement?=?()?=>?{count.value--;}const?increment?=?()?=>?{count.value++;}return?{count,decrement,increment}}
  1. 父組件

<template><h2>{{?count?}}</h2><button?@click="increment">increment</button><button?@click="decrement">decrement</button></template><script>import?{?useCounter?}?from?'./counter.js';export?default?{setup()?{return?{...useCounter(),};}}</script>

響應式計算和偵聽

  1. computed

const?count?=?ref(1)/*不支持修改【只讀的】?*/const?plusOne?=?computed(()?=>?count.value?+?1)plusOne.value++?//?錯誤!/*【可更改的】?*/const?plusOne?=?computed({get:?()?=>?count.value?+?1,set:?(val)?=>?{count.value?=?val?-?1},})
  1. watch

//?直接偵聽一個?refconst?count?=?ref(0)watch(count,?(count,?prevCount)?=>?{/*?...?*/})//?也可以使用數組來同時偵聽多個源watch([fooRef,?barRef],?([foo,?bar],?[prevFoo,?prevBar])?=>?{/*?...?*/})
  1. watchEffect

  • 定義:在響應式地跟蹤其依賴項時立即運行一個函數,并在更改依賴項時重新運行它

  • 第一個參數:effect,顧名思義,就是包含副作用的函數。如下代碼中,副作用函數的作用是:當 count 被訪問時,旋即(隨即)在控制臺打出日志。

  • 返回值:也是一個函數,顯式調用可以清除watchEffect,組件卸載時會被隱式調用

const?count?=?ref(0);const?stop?=?watchEffect(()?=>?console.log(count.value));?//?->?logs?0setTimeout(()?=>?{count.value++;?//?->?logs?1},?100);//?清除watchEffectstop();
  • 清除副作用(onInvalidate)

watchEffect 的第一個參數——effect函數——自己也有參數:叫onInvalidate,也是一個函數,用于清除 effect 產生的副作用。

onInvalidate 被調用的時機很微妙:它只作用于異步函數,并且只有在如下兩種情況下才會被調用:

  1. effect 函數被重新調用時

  2. 當監聽器被注銷時(如組件被卸載了)

import?{?asyncOperation?}?from?"./asyncOperation";const?id?=?ref(0);watchEffect((onInvalidate)?=>?{const?token?=?asyncOperation(id.value);//?onInvalidate?會在?id?改變時或停止偵聽時,取消之前的異步操作(asyncOperation)onInvalidate(()?=>?{token.cancel();});});
  • 第二個參數:options

主要作用是指定調度器,即何時運行副作用函數。

//?fire?before?component?updateswatchEffect(()?=>?{/*?...?*/},{flush:?"pre",onTrigger(e)?{//?依賴項變更導致副作用被觸發時,被調用debugger;},onTrack(e)?{//?依賴項變更會導致重新追蹤依賴時,被調用【調用次數為被追蹤的數量】debugger},});

三、源碼

未完待續...

四、其他相關

Vite2.0,2月17號正式發布

中文文檔:https://cn.vitejs.dev/

五、感悟

優點:很優秀

缺點:他的對手(React),更優秀

雖然好多地方神似React,但是我們也可以從中看出,他們的都源于比較成熟的編程范式——FP(Functional Programming)。

框架只是工具,解決問題才是終極目標;我們還是要把重點放在領悟框架的設計思想上;悟到了,才是真正掌握了解決問題的手段。(抄的)

參考文檔:

https://juejin.cn/post/6858558735695937544#heading-0

https://blog.csdn.net/qq_34998786/article/details/113287653

https://www.jianshu.com/p/ad38a1f27d0f

https://juejin.cn/post/6844904134303301645

https://juejin.cn/post/6858558735695937544#heading-25

https://juejin.cn/post/6888925879243079687

https://www.jianshu.com/p/a8fdf52d0bcf

參考資料

[1]

Vue3中文文檔: https://v3.cn.vuejs.org/

- END -

46cbbc2ff9fc5acae5ff4f2bbeb20ae3.gif

·················?若川簡介?·················

你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》20余篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經寫了7篇,點擊查看年度總結。
同時,最近組織了源碼共讀活動,幫助3000+前端人學會看源碼。公眾號愿景:幫助5年內前端人走向前列。

83fef62422ca7764f77a8990243028c1.png

識別方二維碼加我微信、拉你進源碼共讀

今日話題

略。分享、收藏、點贊、在看我的文章就是對我最大的支持~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/274927.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/274927.shtml
英文地址,請注明出處:http://en.pswp.cn/news/274927.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

改錯3-38

#include<iostream.h>class time{private:int hour,minute,second;public:void settime(int h,int m,int s) { hour(h>0&&h<24)?h:0; minute(m>0&&m<60)?m:0; second(s>0&&s<60)?s:0; }void sh…

魔獸懷舊網站模塊下載_一個人的網站重新設計和懷舊

魔獸懷舊網站模塊下載Despite how I look, I’m the kind kind of person that loves to play old video games. (Full disclosure: I look exactly like the kind of person that loves to play old video games).盡管我長得很帥&#xff0c;但我還是一個喜歡玩舊視頻游戲的人…

華為架構師談如何理解運用模塊與微服務

模塊化還是微服務&#xff1f; 我們的業務由一個大型應用轉向微服務的時候&#xff0c;除了很好展示漂亮的PPT&#xff0c;提升KPI之外&#xff0c;實際操作時將整個業務切成微型服務似乎也不費吹灰之力。但這種方法真的是我們的最佳選擇嗎&#xff1f;確實&#xff0c;維護凌亂…

Node.js 可以和 Web 實現 HTTP 請求的跨平臺兼容了!

大家好&#xff0c;我是若川。持續組織了6個月源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列大家好…

zeplin加載 不出圖片_為什么Zeplin不能解決您的所有問題

zeplin加載 不出圖片Design handover involves communicating the visual styles and behaviours of your design so they can be translated into code.設計移交涉及傳達設計的視覺樣式和行為&#xff0c;以便可以將它們轉換為代碼。 Back in the Dark Ages of digital desig…

POJ 基礎數學

數學 組合數學 POJ3252,poj1850,poj1019,poj1942 數論 poj2635, poj3292,poj1845,poj2115 計算方法&#xff08;二分&#xff09; poj3273,poj3258,poj1905,poj3122 組合數學 poj 3252 題意&#xff1a;如果一個數是round number&#xff0c;則它的二進制表示中&#xff…

使用uwsgi和gunicorn部署Django項目

https://uwsgi-docs.readthedocs.io/en/latest/Management.html https://uwsgi-docs.readthedocs.io/en/latest/Management.html 先了解下相關殺進程命令 ps -ef|grep uwsgi|grep -v grep|awk {print $2}|xargs kill -9//查看uwsgi相關接口 ps -ef|grep uwsgi #查看相關端口 ne…

推薦2022前端必看的新書 《Vue.js設計與實現》

大家好&#xff0c;我是若川。持續組織了6個月源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列這本新…

漢堡菜單_漢堡菜單-可訪問性和用戶體驗設計原則的挑戰?

漢堡菜單重點 (Top highlight)I was recently designing a hamburger menu for a client and before I knew it, I had embarked on this journey where I was reading article after article about the accessibility issues which accompany a hamburger icon. Turns out, th…

Server2012R2 ADFS3.0 The same client browser session has made '6' requests in the last '13'seconds

本問題是在windows server2012R2系統ADFS3.0環境下遇到的&#xff0c;CRM2013部署ADFS后運行一段時間(大概有一兩個月)后在IE瀏覽器中訪問登陸界面點擊登陸后就報以下錯誤 “Microsoft.IdentityServer.Web.InvalidRequestException: MSIS7042: The same client browser session…

(原創)RHEL/CentOS 5.x使用yum快速安裝MySQL 5.5.x

PS&#xff1a;MySQL 5.5系列成為穩定版已經有一段時間了&#xff0c;但據我調查了解&#xff0c;在生產環境中還是以5.1系列為主。在國內的大公司里&#xff0c;只確定金山在使用5.5了。 公司的其中幾臺廣告統計服務器&#xff0c;之前的運維直接用了自帶安裝的MySQL 5.0系列。…

又一個基于 Esbuild 的神器!esno

大家好&#xff0c;我是若川。持續組織了6個月源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan02 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列esno我…

c# ui 滾動 分頁_UI備忘單:分頁,無限滾動和“加載更多”按鈕

c# ui 滾動 分頁重點 (Top highlight)When you have a lot of content, you have to rely on one of these three patterns to load it. So, which is best? What will your users like? What do most platforms use? These are the questions we will explore today.當內容…

1.20(設計模式)模板模式

模板模式&#xff0c;定義了一個模板&#xff0c;模板內容通過子類實現模板的抽象方法去添加。 就類似學校需要建一個新校區&#xff0c;新校區有多棟宿舍&#xff0c;找了多個施工方&#xff0c;每個施工方負責一棟宿舍樓。 各個施工方都有自己的想法&#xff0c;建造的宿舍樓…

少年,看你異于常人,有空花2小時來參加有3000人的源碼共讀嘛~

大家好&#xff0c;我是若川。按照從易到難的順序&#xff0c;前面幾期&#xff08;比如&#xff1a;validate-npm-package-name、axios工具函數&#xff09;很多都只需要花2-3小時就能看完&#xff0c;并寫好筆記。但收獲確實很大。開闊視野、查漏補缺、升職加薪。已經有400筆…

HDU 3488 KM

http://acm.hdu.edu.cn/showproblem.php?pid3488 依然KM&#xff0c; 可以最小費用流 與HDU1853 差不多&#xff0c;但是1853要判斷是否滿足回路的的條件&#xff0c;KM還不會判回路&#xff0c;所以做1853時學了最小費用流做的&#xff0c;說是學最小費用流 只是皮毛了。。…

Java 面向對象的程序設計(二)

編寫一個java程序&#xff0c;設計一個汽車類Vehicle&#xff0c;包含的屬性有車輪的個數wheels和車重weight。小汽車類Car是Vehicle的子類&#xff0c;包含的屬性有載人數loader。卡車類Truck是Car類的子類&#xff0c;其中包含的屬性有載重量payload。每個類都有構造方法和輸…

16位調色板和32位調色板_使調色板可訪問

16位調色板和32位調色板Accessibility has always been a tough sell. Admittedly, less so than in the ‘nineties, when no prospective client was interested. But even today — more enlightened times — the majority of companies I encounter still prefer to make …

從零開始發布自己的NPM包

大家好&#xff0c;我是若川。持續組織了6個月源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan02 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列在Ver…

flash不能訪問本地文件

flash出現"不能訪問本地資源";解決方案 linux下&#xff0c;如果沒有文件夾自行創建 在/home/{user}/.macromedia/Flash_Player/#Security/FlashPlayerTrust下面&#xff0c;隨便建個文本文件&#xff0c;比如1.txt 然后寫入路徑&#xff0c;最省事的辦法直接來個/ 兇…