亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄
關(guān)鍵要點(diǎn)
簡要探索 Vue 2 響應(yīng)式機(jī)制
更改檢測(cè)注意事項(xiàng)
Vue 3 響應(yīng)式機(jī)制的工作原理
探索 Vue 3 響應(yīng)式 API
基本方法
類型檢查方法
更多 Ref 方法
淺層方法
轉(zhuǎn)換方法
computed 和 watch 方法
結(jié)論
Vue 3 響應(yīng)式系統(tǒng)常見問題 (FAQ)
什么是 Vue 3 響應(yīng)式系統(tǒng)?
Vue 3 響應(yīng)式系統(tǒng)與 Vue 2 有何不同?
如何在我的應(yīng)用程序中使用 Vue 3 響應(yīng)式系統(tǒng)?
ref 函數(shù)在 Vue 3 響應(yīng)式機(jī)制中的作用是什么?
Vue 3 中 reactive 和 ref 有什么區(qū)別?
Vue 3 如何處理數(shù)組的響應(yīng)式?
Vue 3 響應(yīng)式機(jī)制中的 toRefs 函數(shù)是什么?
如何阻止 Vue 3 中的對(duì)象具有響應(yīng)性?
Vue 3 響應(yīng)式機(jī)制中的 computed 函數(shù)是什么?
Vue 3 如何處理 Map 和 Set 的響應(yīng)式?
首頁 web前端 js教程 了解VUE 3中的新反應(yīng)性系統(tǒng)

了解VUE 3中的新反應(yīng)性系統(tǒng)

Feb 10, 2025 am 08:53 AM

Understanding the New Reactivity System in Vue 3

現(xiàn)代前端框架的核心組成部分之一是響應(yīng)式系統(tǒng)。它們是讓應(yīng)用實(shí)現(xiàn)高交互性、動(dòng)態(tài)性和響應(yīng)性的魔法棒。理解響應(yīng)式系統(tǒng)是什么以及如何在實(shí)踐中應(yīng)用它,對(duì)于每個(gè) Web 開發(fā)人員來說都是一項(xiàng)至關(guān)重要的技能。

響應(yīng)式系統(tǒng)是一種機(jī)制,它自動(dòng)地將數(shù)據(jù)源(模型)與數(shù)據(jù)表示(視圖)層保持同步。每當(dāng)模型發(fā)生變化時(shí),視圖都會(huì)重新渲染以反映這些變化。

讓我們以一個(gè)簡單的 Markdown 編輯器為例。它通常有兩個(gè)窗格:一個(gè)用于編寫 Markdown 代碼(修改底層模型),另一個(gè)用于預(yù)覽編譯后的 HTML(顯示更新后的視圖)。當(dāng)您在編寫窗格中編寫內(nèi)容時(shí),它會(huì)立即且自動(dòng)地在預(yù)覽窗格中預(yù)覽。當(dāng)然,這只是一個(gè)簡單的例子。通常情況要復(fù)雜得多。

在許多情況下,我們要顯示的數(shù)據(jù)取決于其他一些數(shù)據(jù)。在這種情況下,會(huì)跟蹤依賴項(xiàng)并相應(yīng)地更新數(shù)據(jù)。例如,假設(shè)我們有一個(gè) fullName 屬性,它取決于 firstName 和 lastName 屬性。當(dāng)任何依賴項(xiàng)被修改時(shí),fullName 屬性會(huì)自動(dòng)重新計(jì)算,結(jié)果會(huì)顯示在視圖中。

既然我們已經(jīng)確定了什么是響應(yīng)式,那么現(xiàn)在是時(shí)候?qū)W習(xí)新的 Vue 3 響應(yīng)式機(jī)制的工作原理以及如何在實(shí)踐中使用它了。但在我們這樣做之前,我們將快速瀏覽一下舊的 Vue 2 響應(yīng)式機(jī)制及其缺點(diǎn)。

關(guān)鍵要點(diǎn)

  • Vue 3 引入了一個(gè)完全改進(jìn)的響應(yīng)式系統(tǒng),利用 ES6 Proxy 和 Reflect API,增強(qiáng)了靈活性和功能。
  • Vue 3 中的新響應(yīng)式系統(tǒng)自動(dòng)跟蹤和更新應(yīng)用程序狀態(tài)中的更改,支持更復(fù)雜的數(shù)據(jù)結(jié)構(gòu),如 Map 和 Set。
  • Vue 3 的 reactive、refreadonly 方法允許開發(fā)人員更精細(xì)地控制數(shù)據(jù)響應(yīng)性,其中 ref 用于基本類型,reactive 用于對(duì)象。
  • 高級(jí)響應(yīng)式 API 方法(如 computedwatch)為開發(fā)人員提供了工具,通過有效地管理依賴項(xiàng)和副作用來創(chuàng)建更動(dòng)態(tài)和響應(yīng)的應(yīng)用程序。
  • Vue 3 解決了 Vue 2 響應(yīng)式系統(tǒng)中發(fā)現(xiàn)的限制,例如檢測(cè)數(shù)組長度和對(duì)象屬性添加的更改。
  • 盡管 Vue 3 響應(yīng)式系統(tǒng)具有優(yōu)勢(shì),但它僅在 ES6 環(huán)境中受支持,并且在身份比較方面,響應(yīng)式代理和原始對(duì)象有所不同。

簡要探索 Vue 2 響應(yīng)式機(jī)制

Vue 2 中的響應(yīng)式機(jī)制或多或少是“隱藏的”。我們將任何內(nèi)容放入 data 對(duì)象中,Vue 都會(huì)隱式地使其具有響應(yīng)性。一方面,這簡化了開發(fā)人員的工作,但另一方面,它也導(dǎo)致靈活性降低。

在幕后,Vue 2 使用 ES5 Object.defineProperty() 將 data 對(duì)象的所有屬性轉(zhuǎn)換為gettersetter。對(duì)于每個(gè)組件實(shí)例,Vue 創(chuàng)建一個(gè)依賴項(xiàng)觀察器實(shí)例。在組件渲染期間作為依賴項(xiàng)收集/跟蹤的任何屬性都會(huì)由觀察器記錄。稍后,當(dāng)依賴項(xiàng)的 setter 被觸發(fā)時(shí),觀察器會(huì)收到通知,組件會(huì)重新渲染并更新視圖。這基本上就是所有魔法的工作原理。不幸的是,有一些需要注意的地方。

更改檢測(cè)注意事項(xiàng)

由于 Object.defineProperty() 的限制,Vue 無法檢測(cè)某些數(shù)據(jù)更改。這些包括:

  • 向?qū)ο筇砑?刪除屬性(例如 obj.newKey = value)
  • 通過索引設(shè)置數(shù)組項(xiàng)(例如 arr[index] = newValue)
  • 修改數(shù)組的長度(例如 arr.length = newLength)

幸運(yùn)的是,為了處理這些限制,Vue 為我們提供了 Vue.set API 方法,該方法向響應(yīng)式對(duì)象添加一個(gè)屬性,確保新屬性也具有響應(yīng)性,從而觸發(fā)視圖更新。

讓我們?cè)谙旅娴氖纠刑剿魃鲜銮闆r:

<div id="app">
  <h1>Hello! My name is {{ person.name }}. I'm {{ person.age }} years old.</h1>
  <button @click="addAgeProperty">Add "age" property</button>
  <p>Here are my favorite activities:</p>
  <ul>
    <li v-for="(item, index) in activities" :key="index">{{ item }} <button @click="editActivity(index)">Edit</button></li>
  </ul>
  <button @click="clearActivities">Clear the activities list</button>
</div>
const App = new Vue({
  el: '#app',
  data: {
    person: {
      name: "David"
    },
    activities: [
      "Reading books",
      "Listening music",
      "Watching TV"
    ]
  },
  methods: {
    // 1. Add a new property to an object
    addAgeProperty() {
      this.person.age = 30
    },
    // 2. Setting an array item by index
    editActivity(index) {
      const newValue = prompt('Input a new value')
      if (newValue) {
        this.activities[index] = newValue
      }
    },
    // 3. Modifying the length of the array
    clearActivities() {
      this.activities.length = 0
    }
  }
});

在上面的示例中,我們可以看到這三種方法都不起作用。我們無法向 person 對(duì)象添加新屬性。我們無法使用索引編輯 activities 數(shù)組中的項(xiàng)目。我們也無法修改 activities 數(shù)組的長度。

當(dāng)然,這些情況有解決方法,我們將在下一個(gè)示例中探討:

const App = new Vue({
  el: '#app',
  data: {
    person: {
      name: "David"
    },
    activities: [
      "Reading books",
      "Listening music",
      "Watching TV"
    ]
  },
  methods: {
    // 1. Adding a new property to the object
    addAgeProperty() {
      Vue.set(this.person, 'age', 30)
    },
    // 2. Setting an array item by index
    editActivity(index) {
      const newValue = prompt('Input a new value')
      if (newValue) {
        Vue.set(this.activities, index, newValue)
      }
    },
    // 3. Modifying the length of the array
    clearActivities() {
      this.activities.splice(0)
    }
  }
});

在這個(gè)示例中,我們使用 Vue.set API 方法向 person 對(duì)象添加新的 age 屬性,并從 activities 數(shù)組中選擇/修改特定項(xiàng)目。在最后一種情況下,我們只使用 JavaScript 內(nèi)置的 splice() 數(shù)組方法。

如我們所見,這有效,但這有點(diǎn)笨拙,并導(dǎo)致代碼庫不一致。幸運(yùn)的是,在 Vue 3 中,這個(gè)問題已得到解決。讓我們?cè)谙旅娴氖纠锌纯此纳衿嬷帲?/p>

const App = {
  data() {
    return {
      person: {
        name: "David"
      },
      activities: [
        "Reading books",
        "Listening music",
        "Watching TV"
      ]
    }
  },
  methods: {
    // 1. Adding a new property to the object
    addAgeProperty() {
      this.person.age = 30
    },
    // 2. Setting an array item by index
    editActivity(index) {
      const newValue = prompt('Input a new value')
      if (newValue) {
        this.activities[index] = newValue
      }
    },
    // 3. Modifying the length of the array
    clearActivities() {
      this.activities.length = 0
    }
  }
}

Vue.createApp(App).mount('#app')

在這個(gè)使用 Vue 3 的示例中,我們恢復(fù)到第一個(gè)示例中使用的內(nèi)置 JavaScript 功能,現(xiàn)在所有方法都能正常工作。

在 Vue 2.6 中,引入了 Vue.observable() API 方法。它在某種程度上公開了響應(yīng)式系統(tǒng),允許開發(fā)人員顯式地使對(duì)象具有響應(yīng)性。實(shí)際上,這與 Vue 在內(nèi)部包裝 data 對(duì)象所使用的確切方法相同,對(duì)于為簡單場景創(chuàng)建最小的跨組件狀態(tài)存儲(chǔ)很有用。但是,盡管它很有用,但這種單一方法無法與 Vue 3 附帶的完整、功能豐富的響應(yīng)式 API 的功能和靈活性相匹配。我們將在接下來的部分中看到原因。

注意:因?yàn)?Object.defineProperty() 只是一個(gè) ES5 功能且無法模擬,所以 Vue 2 不支持 IE8 及以下版本。

Vue 3 響應(yīng)式機(jī)制的工作原理

Vue 3 中的響應(yīng)式系統(tǒng)已完全重寫,以便利用 ES6 Proxy 和 Reflect API。新版本公開了一個(gè)功能豐富的響應(yīng)式 API,使系統(tǒng)比以前更靈活、更強(qiáng)大。

Proxy API 允許開發(fā)人員攔截和修改目標(biāo)對(duì)象上的低級(jí)對(duì)象操作。代理是對(duì)象的克隆/包裝器(稱為目標(biāo)),并提供特殊函數(shù)(稱為陷阱),這些函數(shù)響應(yīng)特定操作并覆蓋 JavaScript 對(duì)象的內(nèi)置行為。如果您仍然需要使用默認(rèn)行為,則可以使用相應(yīng)的 Reflection API,其方法顧名思義,反映了 Proxy API 的方法。讓我們探索一個(gè)示例,看看這些 API 如何在 Vue 3 中使用:

<div id="app">
  <h1>Hello! My name is {{ person.name }}. I'm {{ person.age }} years old.</h1>
  <button @click="addAgeProperty">Add "age" property</button>
  <p>Here are my favorite activities:</p>
  <ul>
    <li v-for="(item, index) in activities" :key="index">{{ item }} <button @click="editActivity(index)">Edit</button></li>
  </ul>
  <button @click="clearActivities">Clear the activities list</button>
</div>

要?jiǎng)?chuàng)建一個(gè)新的代理,我們使用 new Proxy(target, handler) 構(gòu)造函數(shù)。它接受兩個(gè)參數(shù):目標(biāo)對(duì)象(person 對(duì)象)和處理程序?qū)ο?,該?duì)象定義將攔截哪些操作(get 和 set 操作)。在處理程序?qū)ο笾?,我們使?get 和 set 陷阱來跟蹤何時(shí)讀取屬性以及何時(shí)修改/添加屬性。我們?cè)O(shè)置控制臺(tái)語句以確保方法正常工作。

get 和 set 陷阱采用以下參數(shù):

  • target:由代理包裝的目標(biāo)對(duì)象
  • property:屬性名稱
  • value:屬性值(此參數(shù)僅用于 set 操作)
  • receiver:在其上執(zhí)行操作的對(duì)象(通常是代理)

Reflect API 方法接受與其對(duì)應(yīng)的代理方法相同的參數(shù)。它們用于為給定操作實(shí)現(xiàn)默認(rèn)行為,對(duì)于 get 陷阱是返回屬性名稱,對(duì)于 set 陷阱是如果設(shè)置了屬性則返回 true,否則返回 false。

注釋的 track() 和 trigger() 函數(shù)特定于 Vue,用于跟蹤何時(shí)讀取屬性以及何時(shí)修改/添加屬性。結(jié)果,Vue 會(huì)重新運(yùn)行使用該屬性的代碼。

在示例的最后一部分,我們使用控制臺(tái)語句輸出原始 person 對(duì)象。然后,我們使用另一個(gè)語句讀取代理對(duì)象的屬性名稱。接下來,我們修改 age 屬性并創(chuàng)建一個(gè)新的 hobby 屬性。最后,我們?cè)俅屋敵?person 對(duì)象以查看它是否已正確更新。

這就是 Vue 3 響應(yīng)式機(jī)制的簡要說明。當(dāng)然,實(shí)際實(shí)現(xiàn)要復(fù)雜得多,但希望上面提供的示例足以讓您掌握主要思想。

使用 Vue 3 響應(yīng)式機(jī)制時(shí),還需要考慮以下幾點(diǎn):

  • 它僅適用于支持 ES6 的瀏覽器
  • 響應(yīng)式代理不等于原始對(duì)象

探索 Vue 3 響應(yīng)式 API

最后,我們進(jìn)入 Vue 3 響應(yīng)式 API 本身。在以下部分,我們將探索按邏輯分組的 API 方法。我把方法分組是因?yàn)槲艺J(rèn)為以這種方式呈現(xiàn)更容易記住。讓我們從基礎(chǔ)開始。

基本方法

第一組包括用于控制數(shù)據(jù)響應(yīng)性的最基本方法:

  • ref 接受基本值或普通對(duì)象,并返回一個(gè)響應(yīng)式且可變的 ref 對(duì)象。ref 對(duì)象只有一個(gè)屬性值,它指向基本值或普通對(duì)象。
  • reactive 接受一個(gè)對(duì)象并返回該對(duì)象的響應(yīng)式副本。轉(zhuǎn)換是深層次的,會(huì)影響所有嵌套屬性。
  • readonly 接受 ref 或?qū)ο螅ㄆ胀ɑ蝽憫?yīng)式),并返回原始對(duì)象的只讀對(duì)象。轉(zhuǎn)換是深層次的,會(huì)影響所有嵌套屬性。
  • markRaw 返回對(duì)象本身,并阻止將其轉(zhuǎn)換為代理對(duì)象。

現(xiàn)在讓我們看看這些方法的實(shí)際應(yīng)用:

<div id="app">
  <h1>Hello! My name is {{ person.name }}. I'm {{ person.age }} years old.</h1>
  <button @click="addAgeProperty">Add "age" property</button>
  <p>Here are my favorite activities:</p>
  <ul>
    <li v-for="(item, index) in activities" :key="index">{{ item }} <button @click="editActivity(index)">Edit</button></li>
  </ul>
  <button @click="clearActivities">Clear the activities list</button>
</div>

在這個(gè)示例中,我們探索了四種基本響應(yīng)式方法的使用。

首先,我們創(chuàng)建一個(gè)值為 0 的 counter ref 對(duì)象。然后,在視圖中,我們放置兩個(gè)按鈕,分別遞增和遞減 counter 的值。當(dāng)我們使用這些按鈕時(shí),我們看到 counter 確實(shí)是響應(yīng)式的。

其次,我們創(chuàng)建一個(gè) person 響應(yīng)式對(duì)象。然后,在視圖中,我們放置兩個(gè)輸入控件,分別用于編輯人的姓名和年齡。當(dāng)我們編輯人的屬性時(shí),它們會(huì)立即更新。

第三,我們創(chuàng)建一個(gè) math 只讀對(duì)象。然后,在視圖中,我們?cè)O(shè)置一個(gè)按鈕來使 math 的 PI 屬性的值加倍。但是當(dāng)我們單擊按鈕時(shí),控制臺(tái)中會(huì)顯示一條錯(cuò)誤消息,告訴我們?cè)搶?duì)象是只讀的,我們無法修改其屬性。

最后,我們創(chuàng)建一個(gè) alphabetNumbers 對(duì)象,我們不想將其轉(zhuǎn)換為代理,并將其標(biāo)記為原始對(duì)象。它包含所有字母及其對(duì)應(yīng)的數(shù)字(為簡潔起見,此處僅使用前三個(gè)字母)。此順序不太可能更改,因此我們故意將此對(duì)象保持為普通對(duì)象,這有利于性能。我們?cè)诒砀裰谐尸F(xiàn)對(duì)象內(nèi)容,并設(shè)置一個(gè)按鈕來將 B 屬性的值更改為 3。我們這樣做是為了表明,盡管對(duì)象可以被修改,但這不會(huì)導(dǎo)致視圖重新渲染。

markRaw 非常適合我們不需要使其具有響應(yīng)性的對(duì)象,例如很長的國家代碼列表、顏色名稱及其對(duì)應(yīng)的十六進(jìn)制數(shù)字等等。

最后,我們使用下一節(jié)中描述的類型檢查方法來測(cè)試和確定我們創(chuàng)建的每個(gè)對(duì)象的類型。我們使用 onMounted() 生命周期鉤子在應(yīng)用程序最初呈現(xiàn)時(shí)觸發(fā)這些檢查。

類型檢查方法

此組包含上面提到的所有四個(gè)類型檢查器:

  • isRef 檢查值是否為 ref 對(duì)象。
  • isReactive 檢查對(duì)象是否是由 reactive 創(chuàng)建的響應(yīng)式代理,或者是由 readonly 包裝另一個(gè)由 reactive 創(chuàng)建的代理創(chuàng)建的。
  • isReadonly 檢查對(duì)象是否是由 readonly 創(chuàng)建的只讀代理。
  • isProxy 檢查對(duì)象是否是由 reactive 或 readonly 創(chuàng)建的代理。

更多 Ref 方法

此組包含其他 ref 方法:

  • unref 返回 ref 的值。
  • triggerRef 手動(dòng)執(zhí)行與 shallowRef 綁定的任何效果。
  • customRef 創(chuàng)建一個(gè)自定義 ref,對(duì)它的依賴項(xiàng)跟蹤和更新觸發(fā)具有顯式控制。

淺層方法

此組中的方法是 ref、reactive 和 readonly 的“淺層”等效項(xiàng):

  • shallowRef 創(chuàng)建一個(gè) ref,它只跟蹤其 value 屬性,而不使其值具有響應(yīng)性。
  • shallowReactive 創(chuàng)建一個(gè)響應(yīng)式代理,它只跟蹤它自己的屬性,不包括嵌套對(duì)象。
  • shallowReadonly 創(chuàng)建一個(gè)只讀代理,它只使它自己的屬性變?yōu)橹蛔x,不包括嵌套對(duì)象。

讓我們通過檢查以下示例來更容易地理解這些方法:

<div id="app">
  <h1>Hello! My name is {{ person.name }}. I'm {{ person.age }} years old.</h1>
  <button @click="addAgeProperty">Add "age" property</button>
  <p>Here are my favorite activities:</p>
  <ul>
    <li v-for="(item, index) in activities" :key="index">{{ item }} <button @click="editActivity(index)">Edit</button></li>
  </ul>
  <button @click="clearActivities">Clear the activities list</button>
</div>

這個(gè)示例從創(chuàng)建一個(gè) settings shallow ref 對(duì)象開始。然后,在視圖中,我們添加兩個(gè)輸入控件來編輯其 width 和 height 屬性。但是當(dāng)我們嘗試修改它們時(shí),我們看到它們沒有更新。為了解決這個(gè)問題,我們添加一個(gè)按鈕,它會(huì)更改整個(gè)對(duì)象及其所有屬性?,F(xiàn)在它可以工作了。這是因?yàn)?value 的內(nèi)容(width 和 height 作為單個(gè)屬性)沒有轉(zhuǎn)換為響應(yīng)式對(duì)象,但 value 的變異(整個(gè)對(duì)象)仍然被跟蹤。

接下來,我們創(chuàng)建一個(gè) settingsA shallow reactive 代理,它包含 width 和 height 屬性以及一個(gè)嵌套的 coords 對(duì)象,其中包含 x 和 y 屬性。然后,在視圖中,我們?yōu)槊總€(gè)屬性設(shè)置一個(gè)輸入控件。當(dāng)我們修改 width 和 height 屬性時(shí),我們看到它們會(huì)響應(yīng)式地更新。但是當(dāng)我們嘗試修改 x 和 y 屬性時(shí),我們看到它們沒有被跟蹤。

最后,我們創(chuàng)建一個(gè) settingsB shallow readonly 對(duì)象,它與 settingsA 具有相同的屬性。在這里,當(dāng)我們嘗試修改 width 或 height 屬性時(shí),控制臺(tái)中會(huì)顯示一條錯(cuò)誤消息,告訴我們?cè)搶?duì)象是只讀的,我們無法修改其屬性。另一方面,可以毫無問題地修改 x 和 y 屬性。

來自最后兩個(gè)示例的嵌套 coords 對(duì)象不受轉(zhuǎn)換的影響,并且保持為普通對(duì)象。這意味著它可以自由修改,但它的任何修改都不會(huì)被 Vue 跟蹤。

轉(zhuǎn)換方法

接下來的三種方法用于將代理轉(zhuǎn)換為 ref(s) 或普通對(duì)象:

  • toRef 為源響應(yīng)式對(duì)象上的屬性創(chuàng)建一個(gè) ref。ref 保持與其源屬性的響應(yīng)式連接。
  • toRefs 將響應(yīng)式對(duì)象轉(zhuǎn)換為普通對(duì)象。普通對(duì)象的每個(gè)屬性都是一個(gè)指向原始對(duì)象相應(yīng)屬性的 ref。
  • toRaw 返回響應(yīng)式或只讀代理的原始普通對(duì)象。

讓我們看看這些轉(zhuǎn)換如何在下面的示例中工作:

const App = new Vue({
  el: '#app',
  data: {
    person: {
      name: "David"
    },
    activities: [
      "Reading books",
      "Listening music",
      "Watching TV"
    ]
  },
  methods: {
    // 1. Add a new property to an object
    addAgeProperty() {
      this.person.age = 30
    },
    // 2. Setting an array item by index
    editActivity(index) {
      const newValue = prompt('Input a new value')
      if (newValue) {
        this.activities[index] = newValue
      }
    },
    // 3. Modifying the length of the array
    clearActivities() {
      this.activities.length = 0
    }
  }
});

在這個(gè)示例中,我們首先創(chuàng)建一個(gè)基本 person 響應(yīng)式對(duì)象,我們將將其用作源對(duì)象。

然后,我們將 person 的 name 屬性轉(zhuǎn)換為具有相同名稱的 ref。然后,在視圖中,我們添加兩個(gè)輸入控件——一個(gè)用于 name ref,另一個(gè)用于 person 的 name 屬性。當(dāng)我們修改其中一個(gè)時(shí),另一個(gè)也會(huì)相應(yīng)地更新,因此它們之間的響應(yīng)式連接得以保持。

接下來,我們將 person 的所有屬性轉(zhuǎn)換為包含在 personDetails 對(duì)象中的單個(gè) ref。然后,在視圖中,我們?cè)俅翁砑觾蓚€(gè)輸入控件來測(cè)試我們剛剛創(chuàng)建的一個(gè) ref。如我們所見,personDetails 的 age 與 person 的 age 屬性完全同步,就像在前面的示例中一樣。

最后,我們將 person 響應(yīng)式對(duì)象轉(zhuǎn)換為 rawPerson 普通對(duì)象。然后,在視圖中,我們添加一個(gè)輸入控件來編輯 rawPerson 的 hobby 屬性。但是如我們所見,Vue 不會(huì)跟蹤轉(zhuǎn)換后的對(duì)象。

computed 和 watch 方法

最后一組方法用于計(jì)算復(fù)雜值和“監(jiān)視”特定值:

  • computed 接受 getter 函數(shù)作為參數(shù),并返回一個(gè)不可變的響應(yīng)式 ref 對(duì)象。
  • watchEffect 立即運(yùn)行一個(gè)函數(shù),并響應(yīng)式地跟蹤其依賴項(xiàng),并在依賴項(xiàng)更改時(shí)重新運(yùn)行它。
  • watch 與 Options API 的 this.$watch 和相應(yīng)的 watch 選項(xiàng)完全等效。它正在監(jiān)視特定的數(shù)據(jù)源,并在監(jiān)視的源發(fā)生更改時(shí)在回調(diào)函數(shù)中應(yīng)用副作用。

讓我們考慮以下示例:

<div id="app">
  <h1>Hello! My name is {{ person.name }}. I'm {{ person.age }} years old.</h1>
  <button @click="addAgeProperty">Add "age" property</button>
  <p>Here are my favorite activities:</p>
  <ul>
    <li v-for="(item, index) in activities" :key="index">{{ item }} <button @click="editActivity(index)">Edit</button></li>
  </ul>
  <button @click="clearActivities">Clear the activities list</button>
</div>

在這個(gè)示例中,我們創(chuàng)建一個(gè) fullName computed 變量,它基于 firstName 和 lastName ref 進(jìn)行計(jì)算。然后,在視圖中,我們添加兩個(gè)輸入控件來編輯全名的兩個(gè)部分。如我們所見,當(dāng)我們修改任何一個(gè)部分時(shí),fullName 會(huì)重新計(jì)算,結(jié)果也會(huì)更新。

接下來,我們創(chuàng)建一個(gè) volume ref 并為其設(shè)置一個(gè) watch effect。每次修改 volume 時(shí),effect 都會(huì)運(yùn)行回調(diào)函數(shù)。為了證明這一點(diǎn),在視圖中,我們添加一個(gè)按鈕,將 volume 遞增 1。我們?cè)诨卣{(diào)函數(shù)中設(shè)置一個(gè)條件,測(cè)試 volume 的值是否可以被 3 整除,當(dāng)它返回 true 時(shí),會(huì)顯示一個(gè)警報(bào)消息。effect 在應(yīng)用程序啟動(dòng)時(shí)運(yùn)行一次,并設(shè)置 volume 的值,然后在每次修改 volume 的值時(shí)再次運(yùn)行。

最后,我們創(chuàng)建一個(gè) state ref 并設(shè)置一個(gè) watch 函數(shù)來跟蹤它的更改。一旦 state 發(fā)生更改,回調(diào)函數(shù)就會(huì)執(zhí)行。在這個(gè)示例中,我們添加一個(gè)按鈕,在 playing 和 paused 之間切換 state。每次發(fā)生這種情況時(shí),都會(huì)顯示一條警報(bào)消息。

watchEffect 和 watch 在功能方面看起來非常相似,但它們有一些明顯的區(qū)別:

  • watchEffect 將回調(diào)函數(shù)中包含的所有響應(yīng)式屬性都視為依賴項(xiàng)。因此,如果回調(diào)包含三個(gè)屬性,則所有這些屬性都會(huì)被隱式地跟蹤更改。
  • watch 只跟蹤我們?cè)诨卣{(diào)中作為參數(shù)包含的屬性。此外,它還提供監(jiān)視屬性的先前值和當(dāng)前值。

如您所見,Vue 3 響應(yīng)式 API 提供了大量方法,可用于各種用例。API 非常龐大,在本教程中,我只探討了基礎(chǔ)知識(shí)。有關(guān)更深入的探索、細(xì)節(jié)和邊緣情況,請(qǐng)?jiān)L問響應(yīng)式 API 文檔。

結(jié)論

在本文中,我們介紹了什么是響應(yīng)式系統(tǒng)以及它如何在 Vue 2 和 Vue 3 中實(shí)現(xiàn)。我們看到 Vue 2 有一些缺點(diǎn)在 Vue 3 中得到了成功解決。Vue 3 響應(yīng)式機(jī)制是基于現(xiàn)代 JavaScript 功能的完整重寫。讓我們總結(jié)一下它的優(yōu)缺點(diǎn)。

優(yōu)點(diǎn):

  • 它可以用作獨(dú)立包。例如,您可以將其與 React 一起使用。
  • 由于其功能豐富的 API,它提供了更大的靈活性和功能。
  • 它支持更多的數(shù)據(jù)結(jié)構(gòu)(Map、WeakMap、Set、WeakSet)。
  • 它的性能更好。只有所需的數(shù)據(jù)才會(huì)變?yōu)轫憫?yīng)式。
  • Vue 2 中的數(shù)據(jù)操作注意事項(xiàng)已得到解決。

缺點(diǎn):

  • 它僅適用于支持 ES6 的瀏覽器。
  • 就身份比較 (===) 而言,響應(yīng)式代理不等于原始對(duì)象。
  • 與 Vue 2 的“自動(dòng)”響應(yīng)式機(jī)制相比,它需要更多代碼。

底線是 Vue 3 響應(yīng)式機(jī)制是一個(gè)靈活且強(qiáng)大的系統(tǒng),Vue 和非 Vue 開發(fā)人員都可以使用它。無論您的情況如何,只需抓住它并開始構(gòu)建令人驚嘆的東西即可。

Vue 3 響應(yīng)式系統(tǒng)常見問題 (FAQ)

什么是 Vue 3 響應(yīng)式系統(tǒng)?

Vue 3 響應(yīng)式系統(tǒng)是 Vue.js(一個(gè)流行的 JavaScript 框架)的一個(gè)基本方面。它負(fù)責(zé)跟蹤應(yīng)用程序狀態(tài)中的更改并更新 DOM(文檔對(duì)象模型)以反映這些更改。該系統(tǒng)圍繞“響應(yīng)式對(duì)象”的概念構(gòu)建。當(dāng)這些對(duì)象的屬性發(fā)生更改時(shí),Vue 會(huì)自動(dòng)觸發(fā)必要的更新。這使開發(fā)人員更容易構(gòu)建動(dòng)態(tài)、響應(yīng)式的 Web 應(yīng)用程序。

Vue 3 響應(yīng)式系統(tǒng)與 Vue 2 有何不同?

Vue 3 的響應(yīng)式系統(tǒng)已使用 JavaScript 的 Proxy 對(duì)象完全重寫,與 Vue 2 的 Object.defineProperty 方法相比,它提供了一種更高效、更強(qiáng)大的跟蹤更改的方式。這個(gè)新系統(tǒng)允許 Vue 跟蹤嵌套屬性的更改,這是 Vue 2 的一個(gè)限制。它還減少了內(nèi)存占用并提高了性能。

如何在我的應(yīng)用程序中使用 Vue 3 響應(yīng)式系統(tǒng)?

要使用 Vue 3 響應(yīng)式系統(tǒng),您需要使用 reactive() 函數(shù)包裝您的數(shù)據(jù)。此函數(shù)使對(duì)象及其屬性具有響應(yīng)性。當(dāng)屬性更改時(shí),Vue 將自動(dòng)重新渲染依賴于它的組件。您還可以使用 ref() 函數(shù)使單個(gè)變量具有響應(yīng)性。

ref 函數(shù)在 Vue 3 響應(yīng)式機(jī)制中的作用是什么?

Vue 3 中的 ref() 函數(shù)用于創(chuàng)建對(duì)值的響應(yīng)式引用。它將值包裝在一個(gè)具有單個(gè)屬性“.value”的對(duì)象中,并使此對(duì)象具有響應(yīng)性。這意味著當(dāng)值更改時(shí),使用此 ref 的任何組件都將更新。

Vue 3 中 reactive 和 ref 有什么區(qū)別?

reactive() 和 ref() 都用于在 Vue 3 中使數(shù)據(jù)具有響應(yīng)性,但它們用于不同的場景。reactive() 函數(shù)用于使對(duì)象具有響應(yīng)性,而 ref() 函數(shù)用于使基本值(如字符串或數(shù)字)具有響應(yīng)性。但是,ref() 也可以與對(duì)象一起使用,在這種情況下,它的行為類似于 reactive()。

Vue 3 如何處理數(shù)組的響應(yīng)式?

Vue 3 處理數(shù)組的響應(yīng)式方式與處理對(duì)象的方式相同。如果您使用 reactive() 函數(shù)使數(shù)組具有響應(yīng)性,Vue 將跟蹤對(duì)數(shù)組元素及其長度的更改。這意味著如果您添加、刪除或替換元素,Vue 將更新依賴于該數(shù)組的組件。

Vue 3 響應(yīng)式機(jī)制中的 toRefs 函數(shù)是什么?

Vue 3 中的 toRefs() 函數(shù)用于將響應(yīng)式對(duì)象轉(zhuǎn)換為普通對(duì)象,其中原始對(duì)象的每個(gè)屬性都表示為一個(gè) ref。當(dāng)您想要解構(gòu)響應(yīng)式對(duì)象但仍保持其響應(yīng)性時(shí),這很有用。

如何阻止 Vue 3 中的對(duì)象具有響應(yīng)性?

您可以使用 markRaw() 函數(shù)來防止對(duì)象具有響應(yīng)性。這在某些情況下很有用,在這些情況下,您不希望 Vue 跟蹤對(duì)對(duì)象的更改。

Vue 3 響應(yīng)式機(jī)制中的 computed 函數(shù)是什么?

Vue 3 中的 computed() 函數(shù)用于創(chuàng)建一個(gè)依賴于其他響應(yīng)式屬性的響應(yīng)式屬性。當(dāng)任何依賴項(xiàng)發(fā)生更改時(shí),computed 屬性的值會(huì)自動(dòng)更新。這對(duì)于計(jì)算或轉(zhuǎn)換非常有用,這些計(jì)算或轉(zhuǎn)換應(yīng)在底層數(shù)據(jù)更改時(shí)更新。

Vue 3 如何處理 Map 和 Set 的響應(yīng)式?

Vue 3 的響應(yīng)式系統(tǒng)完全支持 JavaScript 的 Map 和 Set 數(shù)據(jù)結(jié)構(gòu)。如果您使 Map 或 Set 具有響應(yīng)性,Vue 將分別跟蹤其條目或元素的更改。這意味著如果您添加、刪除或替換條目或元素,Vue 將更新依賴于 Map 或 Set 的組件。

以上是了解VUE 3中的新反應(yīng)性系統(tǒng)的詳細(xì)內(nèi)容。更多信息請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請(qǐng)聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動(dòng)的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機(jī)

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強(qiáng)大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)代碼編輯軟件(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72
如何在node.js中提出HTTP請(qǐng)求? 如何在node.js中提出HTTP請(qǐng)求? Jul 13, 2025 am 02:18 AM

在Node.js中發(fā)起HTTP請(qǐng)求有三種常用方式:使用內(nèi)置模塊、axios和node-fetch。1.使用內(nèi)置的http/https模塊無需依賴,適合基礎(chǔ)場景,但需手動(dòng)處理數(shù)據(jù)拼接和錯(cuò)誤監(jiān)聽,例如用https.get()獲取數(shù)據(jù)或通過.write()發(fā)送POST請(qǐng)求;2.axios是基于Promise的第三方庫,語法簡潔且功能強(qiáng)大,支持async/await、自動(dòng)JSON轉(zhuǎn)換、攔截器等,推薦用于簡化異步請(qǐng)求操作;3.node-fetch提供類似瀏覽器fetch的風(fēng)格,基于Promise且語法簡單

JavaScript數(shù)據(jù)類型:原始與參考 JavaScript數(shù)據(jù)類型:原始與參考 Jul 13, 2025 am 02:43 AM

JavaScript的數(shù)據(jù)類型分為原始類型和引用類型。原始類型包括string、number、boolean、null、undefined和symbol,其值不可變且賦值時(shí)復(fù)制副本,因此互不影響;引用類型如對(duì)象、數(shù)組和函數(shù)存儲(chǔ)的是內(nèi)存地址,指向同一對(duì)象的變量會(huì)相互影響。判斷類型可用typeof和instanceof,但需注意typeofnull的歷史問題。理解這兩類差異有助于編寫更穩(wěn)定可靠的代碼。

React與Angular vs Vue:哪個(gè)JS框架最好? React與Angular vs Vue:哪個(gè)JS框架最好? Jul 05, 2025 am 02:24 AM

選哪個(gè)JavaScript框架最好?答案是根據(jù)需求選擇最適合的。1.React靈活自由,適合需要高度定制、團(tuán)隊(duì)有架構(gòu)能力的中大型項(xiàng)目;2.Angular提供完整解決方案,適合企業(yè)級(jí)應(yīng)用和長期維護(hù)的大項(xiàng)目;3.Vue上手簡單,適合中小型項(xiàng)目或快速開發(fā)。此外,是否已有技術(shù)棧、團(tuán)隊(duì)規(guī)模、項(xiàng)目生命周期及是否需要SSR也都是選擇框架的重要因素。總之,沒有絕對(duì)最好的框架,適合自己需求的就是最佳選擇。

JavaScript時(shí)間對(duì)象,某人構(gòu)建了一個(gè)eactexe,在Google Chrome上更快的網(wǎng)站等等 JavaScript時(shí)間對(duì)象,某人構(gòu)建了一個(gè)eactexe,在Google Chrome上更快的網(wǎng)站等等 Jul 08, 2025 pm 02:27 PM

JavaScript開發(fā)者們,大家好!歡迎閱讀本周的JavaScript新聞!本周我們將重點(diǎn)關(guān)注:Oracle與Deno的商標(biāo)糾紛、新的JavaScript時(shí)間對(duì)象獲得瀏覽器支持、GoogleChrome的更新以及一些強(qiáng)大的開發(fā)者工具。讓我們開始吧!Oracle與Deno的商標(biāo)之爭Oracle試圖注冊(cè)“JavaScript”商標(biāo)的舉動(dòng)引發(fā)爭議。Node.js和Deno的創(chuàng)建者RyanDahl已提交請(qǐng)?jiān)笗?,要求取消該商?biāo),他認(rèn)為JavaScript是一個(gè)開放標(biāo)準(zhǔn),不應(yīng)由Oracle

處理諾言:鏈接,錯(cuò)誤處理和承諾在JavaScript中 處理諾言:鏈接,錯(cuò)誤處理和承諾在JavaScript中 Jul 08, 2025 am 02:40 AM

Promise是JavaScript中處理異步操作的核心機(jī)制,理解鏈?zhǔn)秸{(diào)用、錯(cuò)誤處理和組合器是掌握其應(yīng)用的關(guān)鍵。1.鏈?zhǔn)秸{(diào)用通過.then()返回新Promise實(shí)現(xiàn)異步流程串聯(lián),每個(gè).then()接收上一步結(jié)果并可返回值或Promise;2.錯(cuò)誤處理應(yīng)統(tǒng)一使用.catch()捕獲異常,避免靜默失敗,并可在catch中返回默認(rèn)值繼續(xù)流程;3.組合器如Promise.all()(全成功才成功)、Promise.race()(首個(gè)完成即返回)和Promise.allSettled()(等待所有完成)

什么是緩存API?如何與服務(wù)人員使用? 什么是緩存API?如何與服務(wù)人員使用? Jul 08, 2025 am 02:43 AM

CacheAPI是瀏覽器提供的一種緩存網(wǎng)絡(luò)請(qǐng)求的工具,常與ServiceWorker配合使用,以提升網(wǎng)站性能和離線體驗(yàn)。1.它允許開發(fā)者手動(dòng)存儲(chǔ)如腳本、樣式表、圖片等資源;2.可根據(jù)請(qǐng)求匹配緩存響應(yīng);3.支持刪除特定緩存或清空整個(gè)緩存;4.通過ServiceWorker監(jiān)聽fetch事件實(shí)現(xiàn)緩存優(yōu)先或網(wǎng)絡(luò)優(yōu)先等策略;5.常用于離線支持、加快重復(fù)訪問速度、預(yù)加載關(guān)鍵資源及后臺(tái)更新內(nèi)容;6.使用時(shí)需注意緩存版本控制、存儲(chǔ)限制及與HTTP緩存機(jī)制的區(qū)別。

利用Array.Prototype方法用于JavaScript中的數(shù)據(jù)操作 利用Array.Prototype方法用于JavaScript中的數(shù)據(jù)操作 Jul 06, 2025 am 02:36 AM

JavaScript數(shù)組內(nèi)置方法如.map()、.filter()和.reduce()可簡化數(shù)據(jù)處理;1).map()用于一對(duì)一轉(zhuǎn)換元素生成新數(shù)組;2).filter()按條件篩選元素;3).reduce()用于聚合數(shù)據(jù)為單一值;使用時(shí)應(yīng)避免誤用導(dǎo)致副作用或性能問題。

JS綜述:深入研究JavaScript事件循環(huán) JS綜述:深入研究JavaScript事件循環(huán) Jul 08, 2025 am 02:24 AM

JavaScript的事件循環(huán)通過協(xié)調(diào)調(diào)用棧、WebAPI和任務(wù)隊(duì)列來管理異步操作。1.調(diào)用棧執(zhí)行同步代碼,遇到異步任務(wù)時(shí)交由WebAPI處理;2.WebAPI在后臺(tái)完成任務(wù)后將回調(diào)放入相應(yīng)的隊(duì)列(宏任務(wù)或微任務(wù));3.事件循環(huán)檢查調(diào)用棧是否為空,若為空則從隊(duì)列中取出回調(diào)推入調(diào)用棧執(zhí)行;4.微任務(wù)(如Promise.then)優(yōu)先于宏任務(wù)(如setTimeout)執(zhí)行;5.理解事件循環(huán)有助于避免阻塞主線程并優(yōu)化代碼執(zhí)行順序。

See all articles