日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

如何在Vue中使localStorage具有響應(yīng)式(思想實驗)

瀏覽:244日期:2023-01-07 18:45:35

響應(yīng)式是Vue.js的最大特色之一。如果你不知道幕后情況,它也是最神秘的地方之一。例如,為什么它不能用于對象和數(shù)組,而不能用于諸如 localStorage 之類的其他東西?

如何在Vue中使localStorage具有響應(yīng)式(思想實驗)

讓我們回答這個問題,在解決這個問題時,讓Vue響應(yīng)式與 localStorage 一起使用。

如果運行以下代碼,則會看到計數(shù)器顯示為靜態(tài)值,并且不會像我們期望的那樣發(fā)生變化,這是因為setInterval在 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.js實例中的 counter 屬性是響應(yīng)式的,但它不會因為我們更改了它在 localStorage 中的來源而更改。

有多種解決方案,最好的也許是使用Vuex,并保持存儲值與 localStorage 同步。但如果我們需要像本例中那樣簡單的東西呢?我們要深入了解一下Vue.js的響應(yīng)式系統(tǒng)是如何工作的。

Vue 中的響應(yīng)式

當Vue初始化組件實例時,它將觀察data選項。這意味著它將遍歷數(shù)據(jù)中的所有屬性,并使用 Object.defineProperty 將它們轉(zhuǎn)換為getter/setter。通過為每個屬性設(shè)置自定義設(shè)置器,Vue可以知道屬性何時發(fā)生更改,并且可以通知需要對更改做出反應(yīng)的依賴者。它如何知道哪些依賴者依賴于一個屬性?通過接入getters,它可以在計算的屬性、觀察者函數(shù)或渲染函數(shù)訪問數(shù)據(jù)屬性時進行注冊。

// 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 < keys.length; i++) { defineReactive(obj, keys[i]) } } } export function defineReactive (obj, key, ...) { const dep = new Dep() // ... Object.defineProperty(obj, key, { // ... get() { // ... dep.depend() // ... }, set(newVal) { // ... dep.notify() } }) }

所以,為什么 localStorage 不響應(yīng)?因為它不是具有屬性的對象。

但是等一下,我們也不能用數(shù)組定義getter和setter,但Vue中的數(shù)組仍然是反應(yīng)式的。這是因為數(shù)組在Vue中是一種特殊情況。為了擁有響應(yīng)式的數(shù)組,Vue在后臺重寫了數(shù)組方法,并與Vue的響應(yīng)式系統(tǒng)進行了修補。

我們可以對 localStorage 做類似的事情嗎?

覆蓋localStorage函數(shù)

首先嘗試通過覆蓋localStorage方法來修復(fù)最初的示例,以跟蹤哪些組件實例請求了localStorage項目。

// LocalStorage項目鍵與依賴它的Vue實例列表之間的映射。 const storeItemSubscribers = {}; const getItem = window.localStorage.getItem; localStorage.getItem = (key, target) => { console.info('Getting', key); // 收集依賴的Vue實例 if (!storeItemSubscribers[key]) storeItemSubscribers[key] = []; if (target) storeItemSubscribers[key].push(target); // 調(diào)用原始函數(shù) return getItem.call(localStorage, key); }; const setItem = window.localStorage.setItem; localStorage.setItem = (key, value) => { console.info('Setting', key, value); // 更新相關(guān)Vue實例中的值 if (storeItemSubscribers[key]) { storeItemSubscribers[key].forEach((dep) => { if (dep.hasOwnProperty(key)) dep[key] = value; }); } // 調(diào)用原始函數(shù) setItem.call(localStorage, key, value); };

new Vue({ el: '#counter', data: function() { return { counter: localStorage.getItem('counter', this) // 我們現(xiàn)在需要傳遞“this” } }, computed: { even() { return this.counter % 2 == 0; } }, template: `<div> <div>Counter: {{ counter }}</div> <div>Counter is {{ even ? ’even’ : ’odd’ }}</div> </div>` });

setInterval(() => { const counter = localStorage.getItem('counter'); localStorage.setItem('counter', +counter + 1); }, 1000);

在這個例子中,我們重新定義了 getItem 和 setItem,以便收集和通知依賴 localStorage 項目的組件。在新的 getItem 中,我們注意到哪個組件請求了哪個項目,在 setItems 中,我們聯(lián)系所有請求該項目的組件,并重寫它們的數(shù)據(jù)屬性。

為了使上面的代碼工作,我們必須向 getItem 傳遞一個對組件實例的引用,這就改變了它的函數(shù)簽名。我們也不能再使用箭頭函數(shù)了,因為否則我們就不會有正確的 this 值。

如果我們想做得更好,就必須更深入地挖掘。例如,我們?nèi)绾卧诓伙@式傳遞依賴者的情況下跟蹤它們?

如何在Vue中使localStorage具有響應(yīng)式(思想實驗)

Vue如何收集依賴關(guān)系

為了獲得啟發(fā),我們可以回到Vue的響應(yīng)式系統(tǒng)。我們之前曾看到,訪問數(shù)據(jù)屬性時,數(shù)據(jù)屬性的 getter 將使調(diào)用者訂閱該屬性的進一步更改。但是它怎么知道是誰做的調(diào)用呢?當我們得到一個數(shù)據(jù)屬性時,它的 getter 函數(shù)沒有任何關(guān)于調(diào)用者是誰的輸入。Getter函數(shù)沒有輸入,它怎么知道誰要注冊為依賴者呢?

每個數(shù)據(jù)屬性維護一個需要在Dep類中進行響應(yīng)的依賴項列表。如果我們在此類中進行更深入的研究,可以看到只要在注冊依賴項時就已經(jīng)在靜態(tài)目標變量中定義了依賴項。這個目標是由一個非常神秘的Watche類確定的。實際上,當數(shù)據(jù)屬性更改時,將實際通知這些觀察程序,并且它們將啟動組件的重新渲染或計算屬性的重新計算。

但是,他們又是誰?

當Vue使 data 選項可觀察時,它還會為每個計算出的屬性函數(shù)以及所有watch函數(shù)(不應(yīng)與Watcher類混為一談)以及每個組件實例的render函數(shù)創(chuàng)建watcher。觀察者就像這些函數(shù)的伴侶。他們主要做兩件事:

當它們被創(chuàng)建時,它們會評估函數(shù)。這將觸發(fā)依賴關(guān)系的集合。 當他們被通知他們所依賴的一個值發(fā)生變化時,他們會重新運行他們的函數(shù)。這將最終重新計算一個計算出的屬性或重新渲染整個組件。

在觀察者調(diào)用其負責的函數(shù)之前,有一個重要的步驟發(fā)生了:他們將自己設(shè)置為Dep類中靜態(tài)變量的目標。這樣可以確保在訪問響應(yīng)式數(shù)據(jù)屬性時將它們注冊為從屬。

追蹤誰調(diào)用了localStorage

我們無法完全做到這一點,因為我們無法使用Vue的內(nèi)部機制。但是,我們可以使用Vue的想法,即觀察者可以在調(diào)用其負責的函數(shù)之前,將目標設(shè)置為靜態(tài)屬性。我們能否在調(diào)用 localStorage 之前設(shè)置對組件實例的引用?

如果我們假設(shè)在設(shè)置 data 選項時調(diào)用了 localStorage,則可以將其插入 beforeCreate 和 created 中。這兩個掛鉤在初始化data選項之前和之后都會被觸發(fā),因此我們可以設(shè)置一個目標變量,然后清除該變量,并引用當前組件實例(我們可以在生命周期掛鉤中訪問該實例)。然后,在我們的自定義獲取器中,我們可以將該目標注冊為依賴項。

我們要做的最后一點是使這些生命周期掛鉤成為我們所有組件的一部分,我們可以通過整個項目的全局混合來做到這一點。

// LocalStorage項目鍵與依賴它的Vue實例列表之間的映射 const storeItemSubscribers = {}; // 當前正在初始化的Vue實例 let target = undefined; const getItem = window.localStorage.getItem; localStorage.getItem = (key) => { console.info('Getting', key); // 收集依賴的Vue實例 if (!storeItemSubscribers[key]) storeItemSubscribers[key] = []; if (target) storeItemSubscribers[key].push(target); // 調(diào)用原始函數(shù) return getItem.call(localStorage, key); }; const setItem = window.localStorage.setItem; localStorage.setItem = (key, value) => { console.info('Setting', key, value); // 更新相關(guān)Vue實例中的值 if (storeItemSubscribers[key]) { storeItemSubscribers[key].forEach((dep) => { if (dep.hasOwnProperty(key)) dep[key] = value; }); } // 調(diào)用原始函數(shù) setItem.call(localStorage, key, value); }; Vue.mixin({ beforeCreate() { console.log('beforeCreate', this._uid); target = this; }, created() { console.log('created', this._uid); target = undefined; } });

現(xiàn)在,當我們運行第一個示例時,我們將獲得一個計數(shù)器,該計數(shù)器每秒增加一個數(shù)字。

new Vue({ el: '#counter', data: () => ({ counter: localStorage.getItem('counter') }), computed: { even() { return this.counter % 2 == 0; } }, template: `<div class='component'> <div>Counter: {{ counter }}</div> <div>Counter is {{ even ? ’even’ : ’odd’ }}</div> </div>` });

setInterval(() => { const counter = localStorage.getItem('counter'); localStorage.setItem('counter', +counter + 1); }, 1000);

我們的思想實驗結(jié)束

當我們解決了最初的問題時,請記住這主要是一個思想實驗。它缺少一些功能,例如處理已刪除的項目和未安裝的組件實例。它還具有一些限制,例如組件實例的屬性名稱需要與存儲在 localStorage 中的項目相同的名稱。就是說,主要目標是更好地了解Vue響應(yīng)式在幕后的工作方式并充分利用這一點,因此,我希望你能從所有這些事情中受益。

到此這篇關(guān)于如何在Vue中使localStorage具有響應(yīng)式的文章就介紹到這了,更多相關(guān)Vue localStorage響應(yīng)式內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標簽: Vue
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
欧美极品一区二区三区| 美国欧美日韩国产在线播放| 午夜天堂精品久久久久| 欧美一区二区三区高清视频| 四虎国产精品免费观看| 国产激情在线播放| 久久精品国产网站| 国产精品igao视频网网址不卡日韩| 午夜a一级毛片亚洲欧洲| 日韩在线短视频| 涩涩涩久久久成人精品| 久久久精品五月天| 日韩天堂av| 亚洲国产成人精品女人| 欧美91精品| а√天堂8资源中文在线| 日韩不卡手机在线v区| 成人片免费看| 午夜国产精品视频| 国产一区精品福利| 欧洲一级精品| 国产一区二区亚洲| 四虎8848精品成人免费网站| 中文字幕成在线观看| 精品视频国内| 国产精品福利在线观看播放| 97精品国产| 婷婷综合激情| 日韩亚洲精品在线| 最新国产拍偷乱拍精品| 亚洲成人va| 日韩中文字幕不卡| 免费看欧美美女黄的网站| 美女被久久久| 国产乱人伦精品一区| 国产精品久久久久久久久久10秀 | 国产精品免费看| 黄色欧美日韩| 三级欧美在线一区| 日本不卡一二三区黄网| 成年男女免费视频网站不卡| 欧美精品日日操| 三级精品视频| 亚洲精品网址| 日本韩国欧美超级黄在线观看| 亚洲一区二区日韩| 久久亚洲人体| 色天使综合视频| 国产精品日韩久久久| 一区二区三区四区在线观看国产日韩| 国产亚洲一区二区手机在线观看| 欧美福利专区| 国产亚洲一区二区三区啪| 久久av超碰| 国产一区二区三区四区五区传媒 | 日韩影片在线观看| 美女高潮久久久| 日韩中文在线播放| 免费污视频在线一区| 亚洲高清二区| 国产欧美日韩精品一区二区三区| 六月婷婷综合| 国产精品嫩草99av在线| 亚洲一区欧美| 岛国av在线播放| 国产一级久久| 欧美国产视频| 国产视频欧美| 日韩中文首页| 亚洲+小说+欧美+激情+另类| 国产精品115| 女主播福利一区| 国产精品视频首页| 久久久久久久久丰满| 中文字幕成人| 四虎国产精品免费观看| 免费人成在线不卡| 麻豆精品蜜桃| 国产欧美日韩| 欧美肉体xxxx裸体137大胆| 欧美亚洲三级| 免费成人在线观看| 日韩av在线播放网址| 久久先锋影音| 福利在线免费视频| 欧美国产极品| 蜜臀av亚洲一区中文字幕| 精品国产中文字幕第一页| 欧美+亚洲+精品+三区| 日韩av自拍| 欧美欧美黄在线二区| 91成人精品| 98精品久久久久久久| 麻豆一区二区99久久久久| 亚洲无线观看| 欧美一级精品| 都市激情国产精品| 精品中文字幕一区二区三区| 亚洲在线久久| 日韩亚洲在线| 国产精品丝袜xxxxxxx| 97在线精品| 欧美在线看片| 亚洲福利免费| 91精品国产调教在线观看| 国产精品嫩模av在线| 亚洲在线网站| 亚洲成人日韩| 在线视频精品| 97精品视频在线看| 欧美一区自拍| 丝袜国产日韩另类美女| 蜜臀久久99精品久久久久久9| 免费毛片在线不卡| 日韩欧美二区| 欧美国产偷国产精品三区| 麻豆网站免费在线观看| 麻豆精品久久久| 日韩av一区二区在线影视| 久久午夜精品| 久久亚洲影院| 久久久夜夜夜| 欧美羞羞视频| 日韩久久视频| 午夜久久影院| 免费久久99精品国产自在现线| 日韩精品欧美激情一区二区| 女生影院久久| 亚洲成人三区| 蜜桃久久精品一区二区| 蘑菇福利视频一区播放| 亚洲激情中文| re久久精品视频| 久久久精品五月天| 久久uomeier| 日韩一区二区在线免费| 电影亚洲精品噜噜在线观看| 午夜视频精品| 久久大逼视频| 亚州av一区| 国产精品一区亚洲| av综合电影网站| 久久美女精品| 红桃视频欧美| 99久久视频| 亚洲毛片视频| 国产精品亲子伦av一区二区三区 | 999久久久精品国产| 亚洲精品88| 久久免费高清| 六月丁香综合| 精品久久一区| 天堂av在线| 伊人久久亚洲影院| 日韩久久一区| 国产高清不卡| 日韩一级网站| 日韩精品成人| 国产精品va视频| 亚洲黑丝一区二区| 日韩精品首页| 欧美专区在线| 国产情侣久久| 99久久婷婷| 蜜桃av一区二区三区电影| 国产亚洲电影| 国产高清不卡| 日韩av黄色在线| 国产精品不卡| 视频一区视频二区在线观看| 麻豆国产精品| 中文一区一区三区免费在线观 | 欧美午夜网站| 91亚洲成人| 国产亚洲一级| 91成人在线网站| 日韩一级不卡| 国产精品免费99久久久| 久久久久久色| 国产高潮在线| 免费人成在线不卡| 水蜜桃精品av一区二区| 免费视频国产一区| 欧美一区不卡| 亚洲国产一区二区三区在线播放| 美女久久久久久| 成人va天堂| 欧美一级二级视频| 亚洲天堂黄色| 日韩欧美精品| 日本午夜精品| 99久久视频| 国产欧美激情| 99视频一区| 中文字幕日韩欧美精品高清在线| 久久久久国产精品一区三寸 | 国产劲爆久久| 视频一区二区三区中文字幕| 国产精品久久久久久久久久久久久久久 | 国产精品午夜一区二区三区|