偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Vue 3 已經(jīng) 5 年了,為什么還有公司死守 Vue 2?

開(kāi)發(fā)
咱們先來(lái)看一組數(shù)據(jù),通過(guò) @vue/compiler-sfc(代表 Vue3)? vs vue-template-compiler(代表 Vue2) 來(lái)看下雙方的下載量(PS:因?yàn)?Vue3 合并到主包后,無(wú)法直接區(qū)分 Vue3 和 Vue2 的下載量)

Vue 3 從 2020 年發(fā)布,到現(xiàn)在已經(jīng)正式發(fā)布 5 年了,為什么還有那么多公司依舊在死守 Vue 2?

咱們先來(lái)看一組數(shù)據(jù),通過(guò) @vue/compiler-sfc(代表 Vue3) vs vue-template-compiler(代表 Vue2) 來(lái)看下雙方的下載量(PS:因?yàn)?Vue3 合并到主包后,無(wú)法直接區(qū)分 Vue3 和 Vue2 的下載量)

圖片

通過(guò)數(shù)據(jù)我們可以看出 雖然 @vue/compiler-sfc(代表 Vue3) 的下載量已經(jīng)已經(jīng)遠(yuǎn)遠(yuǎn)超過(guò)了 vue-template-compiler(代表 Vue2)。但是 依然有大約 25% 左右的下載量屬于 vue-template-compiler(代表 Vue2)。

這就證明市面上在運(yùn)行的 Vue 項(xiàng)目中,依然有 至少四分之一 使用的是 Vue2。

那么此時(shí)問(wèn)題就來(lái)了:為什么公司寧愿死守 Vue 2,不愿意遷移到 Vue 3?

1. “技術(shù)債” 太多,項(xiàng)目老且龐大

很多的 政企項(xiàng)目 老項(xiàng)目通常規(guī)模都比較龐大,上千甚至數(shù)千個(gè)頁(yè)面。遷移意味著:

  • 代碼要大改:Options API 寫(xiě)法和 Composition API 寫(xiě)法是有的,幾乎不能無(wú)縫遷移。
  • 生態(tài)要替換:Element UI、vuex、一些定制化的第三方庫(kù),全都得換成對(duì)應(yīng)的 Vue 3 版本。
  • 團(tuán)隊(duì)要學(xué)習(xí):很多老員工只熟悉 Vue 2,遷移要有培訓(xùn)成本。

動(dòng)靜太大。成功了 Leader 沒(méi)什么業(yè)績(jī),一旦出了問(wèn)題 Leader 還得背鍋。 你想想,誰(shuí)會(huì)推動(dòng)這個(gè)事情?

2. 公司盈利能力有限,新功能優(yōu)先級(jí)高于技術(shù)升級(jí)

我們要知道技術(shù)公司,并不是只有大廠。中、小、微 公司的占比可以達(dá)到 98% 以上。

而這些公司的老板們最怕的一件事就是:“原來(lái)跑得好好的項(xiàng)目,升級(jí)后突然一堆 bug?!?/p>

Vue 3 確實(shí)更先進(jìn),但對(duì)于企業(yè)來(lái)說(shuō),穩(wěn)定性 > 技術(shù)新潮。如果業(yè)務(wù)沒(méi)有強(qiáng)烈的驅(qū)動(dòng)(比如:新業(yè)務(wù) Vue2 做不了),一般不會(huì)貿(mào)然升級(jí)。

那么都聊到這里了,接下來(lái)咱們就來(lái)看下面試中常見(jiàn)的 Vue 問(wèn)題

1. Vue 2 和 Vue 3 的響應(yīng)式原理區(qū)別

這是屬于一個(gè)面試中的超常見(jiàn)問(wèn)題,但是很多同學(xué)反而回答的并不好。大部分同學(xué)只會(huì)說(shuō):“Vue2 是 Object.defineProperty。Vue3 是 Proxy” ,然后就 沒(méi)有了....

在現(xiàn)在這么卷的面試場(chǎng)景中,這樣肯定是 不行的呀

Vue 2:defineProperty + 依賴收集

Vue 2 是“攔屬性”的做法(Object.defineProperty 給每個(gè)屬性掛 getter/setter)

  • 初始化時(shí)把對(duì)象 逐個(gè)屬性 轉(zhuǎn)成 getter/setter。讀時(shí)“收集依賴”,寫(xiě)時(shí)“觸發(fā)依賴”。
  • 深度監(jiān)聽(tīng)要 遞歸遍歷,對(duì)象越大,初始化越慢。
  • 新增/刪除屬性感知不到,要 Vue.set(obj, 'x', v) / Vue.delete(obj, 'x')。
  • 數(shù)組是老大難:改長(zhǎng)度、用下標(biāo)改值這種改法,監(jiān)聽(tīng)不到;框架內(nèi)部通過(guò) 包一層原型 去重寫(xiě)會(huì)變更的數(shù)組方法(push/splice/sort……)來(lái)曲線救國(guó)。
// Vue 2 下的老坑
vm.arr[1] = 100     // 不觸發(fā)更新
vm.arr.length = 0   // 不觸發(fā)更新
vm.obj.newKey = 1   // 不觸發(fā)更新
// 需要:
this.$set(vm.arr, 1, 100)
this.$set(vm.obj, 'newKey', 1)
Vue 3:Proxy + WeakMap(桶) + effect

Vue 3 是“攔對(duì)象”的做法(Proxy 一把梭,讀寫(xiě)都能劫持,還能知道讀的是哪個(gè)鍵、做的是什么操作)。

  • 用 Proxy 直接 劫持對(duì)象層級(jí),不需要挨個(gè)屬性包 getter/setter。
  • 依賴收集結(jié)構(gòu)是一個(gè)“大倉(cāng)庫(kù)”:WeakMap(target) -> Map(key) -> Set(effects);讀用 track,寫(xiě)用 trigger。
  • 新增/刪除屬性、數(shù)組下標(biāo)、length 改動(dòng)、Map/Set 等原生集合,統(tǒng)統(tǒng)能感知。
  • 可以“按操作類型”觸發(fā)更精準(zhǔn)(比如 add/delete/clear 對(duì) Map/Set 的影響范圍不同)。
// Vue 3 下這些都能更新
state.arr[1] = 100
state.arr.length = 0
state.obj.newKey = 1
state.set.add(1)
state.map.set('a', 1)

然后給大家一個(gè) 一句話面試背誦版


Vue 2 用 defineProperty 劫持“屬性”,需要深遞歸,新增/刪除屬性和數(shù)組下標(biāo)/length 改動(dòng)監(jiān)聽(tīng)不到,只能靠 set/delete 和重寫(xiě)數(shù)組變更方法補(bǔ)救;

Vue 3 用 Proxy 劫持“對(duì)象”,依賴用 WeakMap -> key -> effects 精確追蹤,支持 Map/Set 等集合,reactive/ref/computed 基于 effect 與調(diào)度器實(shí)現(xiàn),可精細(xì)觸發(fā)、可自定義調(diào)度,性能和心智負(fù)擔(dān)都更優(yōu)。

要是面試官繼續(xù)追問(wèn) “為什么 Vue 3 還能知道我改的是 arr.length?”

你就補(bǔ)一句:因?yàn)?nbsp;Proxy 的 set 能拿到 目標(biāo)、鍵、值,key === 'length' 的時(shí)候做專門(mén)的觸發(fā)邏輯,這在 Vue 2 的 getter/setter 里拿不到這么完整的上下文。

2. Vue 2 和 Vue 3 的 Diff 算法的區(qū)別

這個(gè)也是常見(jiàn)問(wèn)題,但是這里會(huì)涉及到 算法,很多同學(xué)可能對(duì)算法并不是很熟悉。

因此我先把結(jié)論給大家拋出來(lái):


Vue 2 的子節(jié)點(diǎn) diff 更像“四指針+搬磚”(雙端指針?lè)?,必要時(shí)建一張 key→index 表,按匹配到哪就把哪兒搬過(guò)去);


Vue 3 的子節(jié)點(diǎn) diff 是“先粗篩再精算”(兩頭同步 + 中間一坨一次性掛載/卸載;真要挪位置時(shí)再用 LIS 最長(zhǎng)遞增子序列 算出最少移動(dòng))。

Vue 2:雙端指針
  • 針對(duì) keyed children,用四個(gè)游標(biāo)在老/新列表兩頭對(duì)沖:oldStart?newStart、oldEnd?newEnd,還會(huì)嘗試交叉匹配(oldStart ? newEnd、oldEnd ? newStart)。
  • 都沒(méi)對(duì)上時(shí),再用一張 key→index 的表在老列表里定位“同 key 的舊節(jié)點(diǎn)”,找到了就把這個(gè)舊 DOM 挪到合適位置。
  • 沒(méi) key 或沒(méi)找到,就當(dāng)成新節(jié)點(diǎn) 創(chuàng)建 DOM。
  • 這個(gè)策略的好處是實(shí)現(xiàn)簡(jiǎn)單、無(wú)需昂貴的預(yù)處理;但在“局部打散重排”的場(chǎng)景里,移動(dòng)次數(shù)不一定最少,有時(shí)會(huì)“邊比邊搬”,搬得有點(diǎn)多。

小例子(老:[A,B,C,D] → 新:[B,A,D,C]):Vue 2 會(huì)在指針對(duì)沖的過(guò)程中,分別把 A、B、C、D 對(duì)來(lái)對(duì)去,多次移動(dòng),但整體復(fù)雜度仍是 O(n)。

Vue 3:快速 Diff + LIS 的“先粗后細(xì)”

Vue 3 的 patchKeyedChildren 大致分四步,思路更克制:

  • 前綴同步:從左向右比,直到第一對(duì)不等為止。
  • 后綴同步:從右向左比,直到第一對(duì)不等為止。

這兩步很常見(jiàn)于實(shí)際變更(前后加條目),能“秒過(guò)”大段不變區(qū)域。

  • 一坨新增/一坨刪除:

若老的先耗盡,剩下的新節(jié)點(diǎn)整段 一次性掛載;

若新的先耗盡,老列表剩余整段 一次性卸載。

  • 中段重排(真正的“難點(diǎn)”):

對(duì)中間這段構(gòu)建 新Key→新Index 映射,并用一個(gè) source 數(shù)組記錄“老節(jié)點(diǎn)在新位置的索引”(找不到記 -1)。

先把 source 中為 -1 的老 DOM 全部 卸載(新里沒(méi)有了)。

再在 source 上跑 LIS(最長(zhǎng)遞增子序列),LIS 表示“本就順序正確、可以不動(dòng)的那些 DOM”;

不在 LIS 里的,按新順序 最少次數(shù)地插/移,把坑補(bǔ)齊。

同樣的例子(老:[A,B,C,D] → 新:[B,A,D,C]):Vue 3 會(huì)很快同步兩頭(其實(shí)同步不了很多),進(jìn)入中段后通過(guò) source+LIS 直接算出“最少需要?jiǎng)诱l(shuí)”,移動(dòng)次數(shù)更少。

責(zé)任編輯:武曉燕 來(lái)源: 程序員Sunday
相關(guān)推薦

2024-07-04 08:56:35

Vue3項(xiàng)目Pinia

2021-08-23 13:25:25

Vue3CSS前端

2021-01-20 14:25:53

Vue3CSS前端

2025-02-18 08:10:00

Vue 3JavaScrip開(kāi)發(fā)

2025-03-26 10:29:22

Vue3前端API

2024-02-05 21:48:25

VueReactHooks

2021-08-14 23:08:56

蘋(píng)果iPhone XSiPhone 11

2021-10-14 23:11:04

手機(jī)屏幕LCD

2022-03-24 20:42:19

Vue3API 設(shè)計(jì)Vue

2025-10-17 07:10:00

前端開(kāi)發(fā)Vue

2021-12-06 12:48:40

Gosyncatomic

2024-03-05 08:33:52

OptionsAPIcomuted

2021-07-30 05:06:48

Vue 2Vue 3

2023-08-09 10:21:07

Vue 3Reactive

2022-01-12 20:04:09

網(wǎng)絡(luò)故障斷網(wǎng)事件網(wǎng)絡(luò)安全

2025-07-29 08:05:37

2021-10-08 06:10:43

前端技術(shù)Vue

2014-11-18 10:36:36

互聯(lián)網(wǎng)

2019-04-19 11:56:48

框架AI開(kāi)發(fā)

2022-07-13 15:23:57

Vue fiberreact前端
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)