国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄
Vue 中的響應式
首頁 web前端 css教程 如何使局部存儲在VUE中反應性

如何使局部存儲在VUE中反應性

Apr 04, 2025 am 10:16 AM

Vue.js 的響應式系統(tǒng)是其核心優(yōu)勢之一,但對于不了解其底層機制的人來說,可能會感到神秘。例如,為什么它能與對象和數組一起工作,卻不能與其他東西(如 localStorage)一起工作?本文將解答這個問題,并演示如何讓 Vue 的響應式系統(tǒng)與 localStorage 協(xié)同工作。

How to Make localStorage Reactive in Vue

如果運行以下代碼,你會發(fā)現計數器顯示為靜態(tài)值,不會像預期的那樣因間隔改變 localStorage 中的值而變化:

new Vue({
  el: "#counter",
  data: () => ({
    counter: localStorage.getItem("counter")
  }),
  computed: {
    even() {
      return this.counter % 2 == 0;
    }
  },
  template: `<div>
    <div>Counter: {{ counter }}</div>
    <div>Counter is {{ even ? 'even' : 'odd' }}</div>
  </div>`
});
// some-other-file.js
setInterval(() => {
  const counter = localStorage.getItem("counter");
  localStorage.setItem("counter",  counter   1);
}, 1000);

雖然 Vue 實例內的 counter 屬性是響應式的,但僅僅因為我們在 localStorage 中更改了它的來源,它并不會改變。

解決這個問題的方法有很多,最好的方法可能是使用 Vuex 并保持存儲值與 localStorage 同步。但如果我們只需要像這個例子中一樣簡單的解決方案呢?我們必須深入了解 Vue 的響應式系統(tǒng)的工作原理。

Vue 中的響應式

當 Vue 初始化組件實例時,它會觀察 data 選項。這意味著它會遍歷 data 中的所有屬性,并使用 Object.defineProperty 將它們轉換為 getter/setter。通過為每個屬性設置自定義 setter,Vue 就能知道屬性何時發(fā)生變化,并可以通知需要對變化做出反應的依賴項。它如何知道哪些依賴項依賴于某個屬性?通過利用 getter,它可以在計算屬性、觀察者函數或渲染函數訪問數據屬性時進行注冊。

// core/instance/state.js
function initData () {
  // ...
  observe(data)
}
// core/observer/index.js
export function observe (value) {
  // ...
  new Observer(value)
  // ...
}

export class Observer {
  // ...
  constructor (value) {
    // ...
    this.walk(value)
  }

  walk (obj) {
    const keys = Object.keys(obj)
    for (let i = 0; i 
<p>那么,為什么 localStorage 不是響應式的呢?<strong>因為它不是具有屬性的對象。</strong></p>
<p>但是等等。我們也不能用數組定義 getter 和 setter,但在 Vue 中數組仍然是響應式的。這是因為數組在 Vue 中是一個特例。為了擁有響應式數組,Vue 在幕后重寫了數組方法,并將它們與 Vue 的響應式系統(tǒng)整合在一起。</p>
<p>我們可以對 localStorage 做類似的事情嗎?</p>
<h3>重寫 localStorage 函數</h3>
<p>首先,我們可以通過重寫 localStorage 方法來跟蹤哪些組件實例請求了 localStorage 項目,從而修復我們最初的示例。</p>
<p>// localStorage 項目鍵與依賴它的 Vue 實例列表之間的映射
const storeItemSubscribers = {};</p>
<p>const getItem = window.localStorage.getItem;
localStorage.getItem = (key, target) => {
console.info("Getting", key);</p>
<p>// 收集依賴的 Vue 實例
if (!storeItemSubscribers[key]) storeItemSubscribers[key] = [];
if (target) storeItemSubscribers[key].push(target);</p>
<p>// 調用原始函數
return getItem.call(localStorage, key);
};</p>
<p>const setItem = window.localStorage.setItem;
localStorage.setItem = (key, value) => {
console.info("Setting", key, value);</p>
<p>// 更新依賴 Vue 實例中的值
if (storeItemSubscribers[key]) {
storeItemSubscribers[key].forEach((dep) => {
if (dep.hasOwnProperty(key)) dep[key] = value;
});
}</p>
<p>// 調用原始函數
setItem.call(localStorage, key, value);
};</p>
<p>// ... (其余代碼與原文相同)</p>
<p>在這個例子中,我們重新定義了 <code>getItem</code> 和 <code>setItem</code>,以便收集和通知依賴 localStorage 項目的組件。在新的 <code>getItem</code> 中,我們記錄了哪個組件請求了哪個項目,在 <code>setItem</code> 中,我們聯系所有請求該項目并重寫其數據屬性的組件。</p>
<p>為了使上面的代碼工作,我們必須將對組件實例的引用傳遞給 <code>getItem</code>,這會改變它的函數簽名。我們也不能再使用箭頭函數,否則我們將不會有正確的 <code>this</code> 值。</p>
<p>如果我們想做得更好,我們必須更深入地挖掘。例如,我們如何在不顯式地傳遞它們的情況下跟蹤依賴項?</p>
<h3>Vue 如何收集依賴項</h3>
<p>為了獲得靈感,我們可以回到 Vue 的響應式系統(tǒng)。我們之前看到,當訪問數據屬性時,數據屬性的 getter 會將調用者訂閱到該屬性的進一步更改。但它如何知道是誰進行了調用?當我們獲取數據屬性時,它的 getter 函數沒有任何關于調用者是誰的輸入。Getter 函數沒有輸入。它如何知道將誰注冊為依賴項?</p>
<p>每個數據屬性都維護一個其依賴項列表,這些依賴項需要在一個 <code>Dep</code> 類中做出反應。如果我們更深入地研究這個類,我們可以看到,每當注冊依賴項時,依賴項本身就已經在一個靜態(tài)目標變量中定義了。這個目標是由一個迄今為止神秘的 <code>Watcher</code> 類設置的。事實上,當數據屬性發(fā)生變化時,這些觀察者將被實際通知,它們將啟動組件的重新渲染或計算屬性的重新計算。</p>
<p>但是,再說一次,它們是誰?</p>
<p>當 Vue 使數據選項可觀察時,它還會為每個計算屬性函數以及所有觀察函數(不應與 <code>Watcher</code> 類混淆)和每個組件實例的渲染函數創(chuàng)建觀察者。觀察者就像這些函數的伴侶。它們主要做兩件事:</p>
<ol>
<li>
<strong>它們在創(chuàng)建時評估函數。</strong>這會觸發(fā)依賴項的收集。</li>
<li>
<strong>當它們被通知到它們依賴的值已更改時,它們會重新運行其函數。</strong>這最終將重新計算計算屬性或重新渲染整個組件。</li>
</ol>
<p>在觀察者調用它們負責的函數之前,會發(fā)生一個重要的步驟:<strong>它們在 <code>Dep</code> 類中的靜態(tài)變量中將自身設置為目標。</strong>這確保了當訪問響應式數據屬性時,它們會被注冊為依賴項。</p>
<h3>跟蹤誰調用了 localStorage</h3>
<p>我們不能完全做到這一點,因為我們無法訪問 Vue 的內部機制。但是,我們可以使用 Vue 的思想,讓觀察者在調用它負責的函數之前,在一個靜態(tài)屬性中設置目標。我們可以在調用 localStorage 之前設置對組件實例的引用嗎?</p>
<p>如果我們假設在設置數據選項時調用了 localStorage,那么我們可以掛接到 <code>beforeCreate</code> 和 <code>created</code>。這兩個鉤子在初始化數據選項之前和之后觸發(fā),因此我們可以設置,然后清除一個具有對當前組件實例的引用的目標變量(我們可以在生命周期鉤子中訪問它)。然后,在我們的自定義 getter 中,我們可以將此目標注冊為依賴項。</p>
<p>我們必須做的最后一件事是使這些生命周期鉤子成為我們所有組件的一部分。我們可以為整個項目使用全局 mixin 來做到這一點。</p>
<p>// ... (其余代碼與原文相同)</p>
<p>現在,當我們運行初始示例時,我們將得到一個每秒增加數字的計數器。</p>
<p>// ... (其余代碼與原文相同)</p>
<h3>我們的思想實驗的結束</h3>
<p>雖然我們解決了最初的問題,但請記住,這主要是一個思想實驗。它缺少一些功能,例如處理已刪除的項目和已卸載的組件實例。它也有一些限制,例如組件實例的屬性名稱需要與存儲在 localStorage 中的項目名稱相同。也就是說,主要目標是更好地了解 Vue 響應式系統(tǒng)在幕后是如何工作的,并充分利用它,所以我希望這就是你從這一切中獲得的東西。</p>

以上是如何使局部存儲在VUE中反應性的詳細內容。更多信息請關注PHP中文網其他相關文章!

本站聲明
本文內容由網友自發(fā)貢獻,版權歸原作者所有,本站不承擔相應法律責任。如您發(fā)現有涉嫌抄襲侵權的內容,請聯系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Clothoff.io

Clothoff.io

AI脫衣機

Video Face Swap

Video Face Swap

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

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

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

Dreamweaver CS6

Dreamweaver CS6

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

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

如何僅在某些頁面上包括CSS? 如何僅在某些頁面上包括CSS? Jun 11, 2025 am 12:01 AM

選擇性包含CSS在特定頁面上的方法有三種:1.內聯CSS,適用于不常訪問或需要獨特樣式的頁面;2.使用JavaScript條件加載外部CSS文件,適合需要靈活性的情況;3.服務器端包含,適用于使用服務器端語言的場景。這種方法可以優(yōu)化網站性能和可維護性,但需平衡模塊化與性能。

Flexbox與網格:了解CSS布局的關鍵差異 Flexbox與網格:了解CSS布局的關鍵差異 Jun 10, 2025 am 12:03 AM

flexboxisidealforone-dimensionAllayouts,while gridsuitStwo,complex layouts.useflexboxforaligningItemsinasingLeaxisAndGridForRidForPreciseconcontroloverroverroverroverroverroverroverrowsandsininintricatientricatedesigns。

使用HTML彈出案創(chuàng)建自動關閉通知 使用HTML彈出案創(chuàng)建自動關閉通知 Jun 10, 2025 am 09:45 AM

HTML彈出屬性將元素轉換為頂層元素,可以使用按鈕或JavaScript打開和關閉??梢詫棾霭格g回多種方式,但是沒有選擇自動關閉它們。 preethi有一種技術,你可以

什么是'渲染障礙CSS”? 什么是'渲染障礙CSS”? Jun 24, 2025 am 12:42 AM

CSS會阻塞頁面渲染是因為瀏覽器默認將內聯和外部CSS視為關鍵資源,尤其是使用引入的樣式表、頭部大量內聯CSS以及未優(yōu)化的媒體查詢樣式。1.提取關鍵CSS并內嵌至HTML;2.延遲加載非關鍵CSS通過JavaScript;3.使用media屬性優(yōu)化加載如打印樣式;4.壓縮合并CSS減少請求。建議使用工具提取關鍵CSS,結合rel="preload"異步加載,合理使用media延遲加載,避免過度拆分與復雜腳本控制。

如何在無花果中使用Lotties 如何在無花果中使用Lotties Jun 14, 2025 am 10:17 AM

在接下來的教程中,我將向您展示如何在無花果中創(chuàng)建Lottie動畫。我們將使用兩種彩色設計來超越如何在無花果上進行動畫,然后向您展示如何從Figma到Lottie動畫。您只需要免費無花果

打破邊界:用(s)CSS構建湯姆拼圖 打破邊界:用(s)CSS構建湯姆拼圖 Jun 13, 2025 am 11:33 AM

我們對其進行了測試,事實證明,至少在低級邏輯和拼圖行為時,Sass可以替換JavaScript。除了地圖,混音,功能和大量數學外,我們都設法使我們的Tangram難題栩栩如生,沒有J

外部與內部CSS:最好的方法是什么? 外部與內部CSS:最好的方法是什么? Jun 20, 2025 am 12:45 AM

thebestapphachforcssdepprodsontheproject'sspefificneeds.forlargerprojects,externalcsSissBetterDuoSmaintoMaintainability andReusability; forsMallerProjectsorsingle-pageApplications,InternaltCsmightBemoresobleable.InternalCsmightBemorese.it.it'sclucialtobalancepopryseceneceenceprodrenceprodrenceNeed

我的CSS必須在較低的情況下嗎? 我的CSS必須在較低的情況下嗎? Jun 19, 2025 am 12:29 AM

否,CSSDOESNOTHAVETOBEINLOWERCASE.CHOMENDENS,使用flowercaseisrecommondendendending:1)一致性和可讀性,2)避免使用促進性技術,3)潛在的Performent FormanceBenefits,以及4)RightCollaboraboraboraboraboraboraboraboraboraboraboraboraboraboraboraboraborationWithInteams。

See all articles