前言
vue3的響應式API大家應該都特別熟悉,比如ref
、watch
、watchEffect
等。平時大家都是在vue-cli
或者vite
建立的vue專案裡面使用的這些響應式API,今天歐陽給大家帶來一些不一樣的。脫離vue專案,在node.js
專案中使用vue的響應式API。
關注公眾號:【前端歐陽】,給自己一個進階vue的機會
直接上程式碼
話不多說,直接上程式碼。這個是我在本地新建的一個最簡單的node.js
專案,如下圖:
從上圖可以看到我們的node.js
專案依賴只有一個:vue
。並且提供了一個名為dev的指令碼命令,這個指令碼命令實際是在node環境內執行index.js
檔案。
我們來看index.js
檔案,程式碼如下:
const { ref, watch, watchEffect } = require("vue");
const count = ref(0);
// 模擬count變數的值修改
setInterval(() => {
count.value++;
}, 1000);
watch(count, (newVal) => {
console.log("觸發watch", newVal);
});
watchEffect(
() => {
console.log("觸發watchEffect", count.value);
},
{
flush: "sync",
}
);
為了標明index.js
檔案是在node.js
環境中執行的,所以這裡我特地使用require
去匯入vue匯出的ref
、watch
、watchEffect
這三個響應式API。
並且我們還模擬了修改count
響應式變數值的操作,使用setInterval
每隔一秒讓count
的值+1
。
在vue專案中一樣使用watch
和watchEffect
去監聽count
變數的值。
在終端執行yarn dev
,也就是執行node index.js
,如下圖:
從上圖中可以看到在node.js
中的執行結果和預期是一模一樣的。
為什麼可以這樣寫呢?
前面的那個例子是一個node.js
專案,專案中我們並沒有像vue專案那樣去建立一個vue元件,然後在元件裡面去使用響應式API。而是直接在一個普通的node.js
檔案中使用vue暴露出來的響應式API,並且watch
和watchEffect
在監聽的值改變後同樣觸發了對應的watch回撥,那麼這個又是怎麼做到的呢?
這得益於vue3優秀的模組化設計,他將核心功能拆分為多個獨立的模組,如下圖:
比如reactivity
模組中就是響應式的核心程式碼、compiler-core
模組就是編譯相關的核心程式碼。
並且這些模組還被單獨當作npm包進行釋出,命名規則是@vue+模組名
。比如reactivity
模組對應的npm包就是@vue/reactivity
。如下圖:
得益於模組化的設計,響應式相關的API和vue元件並沒有強關聯的關係,所以我們可以在node.js
應用中去直接使用響應式API。
這裡使用到了三個響應式API,分別是:ref
、watch
和watchEffect
。在vue元件中的響應式的實現原理大家多多少少都有所聽聞,其實在node.js
專案中實現原理也是一樣的,接下來我們講講是如何實現響應式的。
在我們這個demo中count
是一個ref的響應式變數,當我們對count
變數進行讀操作時會觸發get
攔截。當我們對count
變數進行寫操作時會觸發set
攔截。
在我們這裡使用watch
和watchEffect
的程式碼是下面這樣的:
watch(count, (newVal) => {
console.log("觸發watch", newVal);
});
watchEffect(
() => {
console.log("觸發watchEffect", count.value);
},
{
flush: "sync",
}
);
當程式碼首次執行到watch
和watchEffect
時都會對count
變數進行讀操作,並且watch
和watchEffect
都傳入了一個回撥函式。
由於對count
變數進行讀操作了,所以就會觸發get
攔截。在get
攔截中會將當前watch的回撥函式作為依賴收集到count
變數中。收集的方式也很簡單,因為count
變數是一個物件,所以使用物件的dep
屬性進行依賴收集。因為dep
屬性是一個集合,所以可以收集多個依賴。
在我們這裡watch
和watchEffect
都觸發了count
變數的get攔截,所以watch
和watchEffect
的回撥函式都被count
變數進行了依賴收集。
當修改count
變數的值時會觸發set
攔截,在set
攔截中做的事情也很簡單。將count
變數收集到的依賴全部取出來,然後執行一遍。這裡收集的依賴是watch
和watchEffect
的回撥函式,所以當count
變數的值改變時會導致watch
和watchEffect
的回撥函式重新執行。
這個是整個流程圖:
從流程圖可以看到響應式的實現原來完全不依賴vue元件,所以我們可以在node.js
專案中使用vue的響應式API,這也是vue的設計奇妙之處。
總結
這篇文章講了我們可以脫離vue專案,直接在node.js
專案中使用vue的響應式API。接著講了響應式的實現原理其實就是依靠get
攔截進行依賴收集,set
攔截進行依賴觸發。
搞清楚響應式原理後,我們發現響應式完全不依賴vue元件,所以我們可以在node.js
專案中使用vue的響應式API,這也是vue的設計奇妙之處。
關注公眾號:【前端歐陽】,給自己一個進階vue的機會