您好,登錄后才能下訂單哦!
小編給大家分享一下Vue.js怎么實現數據響應的方法,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
1、js屬于一種解釋性腳本語言;2、在絕大多數瀏覽器的支持下,js可以在多種平臺下運行,擁有著跨平臺特性;3、js屬于一種弱類型腳本語言,對使用的數據類型未做出嚴格的要求,能夠進行類型轉換,簡單又容易上手;4、js語言安全性高,只能通過瀏覽器實現信息瀏覽或動態交互,從而有效地防止數據的丟失;5、基于對象的腳本語言,js不僅可以創建對象,也能使用現有的對象。
許多前端JavaScript框架(例如Angular,React和Vue)都有自己的數據相應引擎。通過了解相應性及其工作原理,您可以提高開發技能并更有效地使用JavaScript框架。在視頻和下面的文章中,我們構建了您在Vue源代碼中看到的相同類型的Reactivity。
? The Reactivity System
當你第一次看到它時,Vue的響應系統看起來很神奇。拿這個簡單的Vue應用程序:
不知何故,Vue只知道如果價格發生變化,它應該做三件事:
更新我們網頁上的價格值。
重新計算乘以price * quantity的表達式,并更新頁面。
再次調用totalPriceWithTax函數并更新頁面。
但是等等,你應該會覺得奇怪,當價格變化時,Vue如何知道要更新什么,以及它如何跟蹤所有內容?
這不是JavaScript編程常規的工作方式。
如果你不明白,那我們試著看看常規的JavaScript是怎么運行的。例如,如果我運行此代碼:
你覺得它打印什么?由于我們沒有使用Vue,它將打印10。
在Vue,我們希望每當價格或數量更新時,總計都會得到更新。我們想要:
不幸的是,JavaScript是程序性的,而不是被動的,所以這在現實生活中不起作用。為了使數據變化得到相應,我們必須使用JavaScript來使事情表現不同。
?? 問題
我們需要保存計算總數的方式,以便在價格或數量變化時重新運行。
? 解決方案
首先,我們需要一些方法告訴我們的應用程序,“我即將運行的代碼,存儲它,我可能需要你在另一個時間運行它。”然后我們將要運行代碼,如果價格或數量變量得到更新,再次運行存儲的代碼。
請注意,我們在目標變量中存儲了一個匿名函數,然后調用了一個記錄函數。使用ES6箭頭語法我也可以這樣寫:
請注意,我們在目標變量中存儲了一個匿名函數,然后調用了一個記錄函數。使用ES6箭頭語法我也可以這樣寫:
記錄的方法:
我們正在存儲目標(在我們的例子中是{total = price * quantity}),所以我們可以稍后運行它。
這將遍歷存儲陣列中存儲的所有匿名函數并執行它們中的每一個。
然后在我們的代碼中,我們可以:
很簡單吧?如果您需要閱讀并嘗試再次掌握它,這里的代碼就完整了。僅供參考,如果您想知道原因,我會以特定的方式對此進行編碼。
?? 問題
我們可以根據需要繼續記錄目標,但是有一個更強大的解決方案可以擴展我們的應用程序。那就是一個負責維護目標列表的類,當我們需要它們重新運行時,這些目標列表會得到通知。
? 解決方法: 使用Class
我們可以開始解決這個問題的一種方法是將這種行為封裝到它自己的Class中,這是一個實現標準編程觀察者模式的依賴類。
因此,如果我們創建一個JavaScript類來管理我們的依賴項(它更接近Vue處理事物的方式),它可能看起來像這樣:
讓它運行:
它仍然有效,現在我們的代碼感覺更可靠了。只有仍然感覺有點奇怪的是target()的設置和運行。
?? 問題
我們將為每個變量設置一個Dep類,并且很好地封裝了創建需要監視更新的匿名函數的行為。也許觀察者功能可能是為了處理這種行為。
(這只是上面的代碼)
我們可以改為:
? 解決方案:觀察者功能
在我們的Watcher功能中,我們可以做一些簡單的事情:
如您所見,watcher函數接受myFunc參數,將其設置為我們的全局目標屬性,調用dep.depend()以將目標添加為訂閱者,調用目標函數并重置目標。
現在,當我們運行以下內容時:
您可能想知道為什么我們將target實現為全局變量,而不是將其傳遞到我們需要的函數中。這有一個很好的理由,這將在我們的文章結尾處揭曉。
?? 問題
我們有一個Dep類,但我們真正想要的是每個變量都有自己的Dep。在我們繼續之前,先存儲一下數據。
讓我們假設我們的每個屬性(價格和數量)都有自己的內部Dep類。
當我們運行時:
由于訪問了data.price值,我希望price屬性的Dep類將我們的匿名函數(存儲在目標中)推送到其訂閱者數組(通過調用dep.depend())。由于訪問了data.quantity,我還希望quantity屬性Dep類將此匿名函數(存儲在目標中)推送到其訂閱者數組中。
如果我有另一個匿名函數,只訪問data.price,我希望只推送到價格屬性Dep類。
我什么時候想要在價格訂閱者上調用dep.notify()?我希望在設定價格時調用它們。在文章的最后,我希望能夠進入控制臺并執行:
我們需要一些方法來掛鉤數據屬性(如價格或數量),所以當它被訪問時我們可以將目標保存到我們的訂閱者數組中,當它被更改時,運行存儲在我們的訂閱者數組中的函數。
? 解決方案:Object.defineProperty()
我們需要了解Object.defineProperty()函數,它是簡單的ES5 JavaScript。它允許我們為屬性定義getter和setter函數。在我向您展示如何在Dep類中使用它之前,先簡單展示一下改函數的用法。
如您所見,它只記錄兩行。但是,它實際上并沒有獲取或設置任何值,因為我們過度使用了該功能。我們現在加回來吧。 get()期望返回一個值,而set()仍然需要更新一個值,所以讓我們添加一個internalValue變量來存儲我們當前的價格值。
既然我們的get和set工作正常,您認為將打印到控制臺的是什么?
因此,當我們獲取并設置值時,我們可以獲得通知。通過一些遞歸,我們可以為數組中的所有項運行它
FYI,Object.keys(data)返回對象鍵的數組。
現在一切都有getter和setter,我們在控制臺上看到了這一點。
? Putting both ideas together
當像這樣的一段代碼運行并獲得價格的價值時,我們希望價格記住這個匿名函數(目標)。這樣,如果價格變化,或者設置為新值,它將觸發此函數以重新運行,因為它知道此行依賴于它。所以你可以這樣想。
Get =>記住這個匿名函數,當我們的值發生變化時,我們會再次運行它。
Set =>運行保存的匿名函數,我們的值剛改變。
或者就我們的Dep Class而言
Price accessed (get) => 調用dep.depend()來保存當前目標
Price set => 在價格上調用dep.notify(),重新運行所有目標
讓我們結合這兩個想法,并完成我們的最終代碼。
現在看看會發生什么。
正是我們所希望的!價格和數量都確實是得到了實時的響應的!只要價格或數量的價值得到更新,我們的總代碼就會重新運行。
Vue文檔中的這個插圖現在應該開始有意義了。
你看到那個漂亮的紫色數據圈了嗎?看起來應該很眼熟!每個組件實例都有一個從getter(紅線)收集依賴項的服務觀察器實例(藍色)。當稍后調用設置程序時,它會通知監視程序,它將導致組件重新呈現。下面是我自己的一些注釋的圖片。
是的,現在是不是覺得更有意義了。
顯然,Vue做的可能更復雜更驚喜,但你現在知道了基礎知識。
? 總結:所以我們學了什么?如何創建一個Dep類來收集依賴項(依賴)并重新運行所有依賴項(notify)。如何創建一個觀察程序來管理我們正在運行的代碼,這些代碼可能需要作為依賴項添加(target)。如何使用Object.defineProperty()創建getter和setter。
看完了這篇文章,相信你對“Vue.js怎么實現數據響應的方法”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。