自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

前端必讀:Vue響應(yīng)式系統(tǒng)大PK

開發(fā) 前端
響應(yīng)系統(tǒng)是一種使自動(dòng)使數(shù)據(jù)源(模型)與數(shù)據(jù)表示(視圖)層自動(dòng)保持同步的機(jī)制。每次模型更改時(shí),都會(huì)重新渲染視圖。

 [[400474]]

響應(yīng)式系統(tǒng)(Reactivity systems)是現(xiàn)代前端框架的關(guān)鍵部分之一。應(yīng)用系統(tǒng)的的高度交互性、動(dòng)態(tài)性和響應(yīng)能力全靠它支持。每個(gè)Web開發(fā)人員而言都應(yīng)該了解這一系統(tǒng)的功能和實(shí)踐操作。

原理

響應(yīng)系統(tǒng)是一種使自動(dòng)使數(shù)據(jù)源(模型)與數(shù)據(jù)表示(視圖)層自動(dòng)保持同步的機(jī)制。每次模型更改時(shí),都會(huì)重新渲染視圖。

以一個(gè)簡(jiǎn)單的Markdown編輯器為例。通常編輯器有兩個(gè)窗格:一個(gè)窗格用于編寫Markdown代碼(用于修改基礎(chǔ)模型),另一個(gè)窗格用于預(yù)覽已編譯的HTML(顯示已更新的視圖)。當(dāng)我們?cè)跁鴮懘案裰袑憱|西時(shí),它會(huì)立即在預(yù)覽窗格中自動(dòng)預(yù)覽。這個(gè)例子比較簡(jiǎn)單,在實(shí)際情況中會(huì)復(fù)雜很多。

在許多情況下,我們要顯示的數(shù)據(jù)取決于其他數(shù)據(jù)。在這種情況下,需要跟蹤相關(guān)數(shù)據(jù),并根據(jù)跟蹤情況來更新數(shù)據(jù)。例如,我們有一個(gè)fullName,該屬性由firstName和lastName屬性組成。修改其任何依賴項(xiàng)后,fullName將自動(dòng)重新評(píng)估,并在視圖中顯示結(jié)果。

了解什么是響應(yīng)式系統(tǒng)后,在了解Vue 3中的響應(yīng)系統(tǒng)如何工作以及如何在實(shí)踐中使用之前,讓我們一起來快速回顧一下Vue 2中的響應(yīng)系統(tǒng)內(nèi)容及其注意事項(xiàng)。

Vue 2的響應(yīng)式系統(tǒng)簡(jiǎn)介

Vue 2中的響應(yīng)或多或少會(huì)被“隱藏”。無論我們放置在data對(duì)象中的是什么,Vue都會(huì)使其隱式反應(yīng)(reactive implicitly)。這樣雖然可以使開發(fā)人員的工作更加輕松,但靈活度卻會(huì)不可避免的降低。

在幕后,Vue 2使用ES5 Object.defineProperty將data對(duì)象的所有屬性轉(zhuǎn)換為getter和setter。對(duì)于每個(gè)組件實(shí)例,Vue創(chuàng)建一個(gè)依賴關(guān)系觀察程序?qū)嵗?,觀察者會(huì)記錄組件渲染期間依賴收集/跟蹤的任何屬性。當(dāng)屬性觸發(fā)依賴項(xiàng)的設(shè)置器時(shí),將通知觀察者,并將組件重新渲染并更新視圖。但是卻也會(huì)有一些問題存在。

變更檢測(cè)警告

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

  • 給對(duì)象添加屬性或把對(duì)象移除屬性(例如obj.newKey = value)
  • 按索引設(shè)置數(shù)組項(xiàng)(例如arr[index] = newValue)
  • 修改數(shù)組的長(zhǎng)度(例如arr.length = newLength)
    不過為了解決這些問題, Vue為提供了Vue.set API方法,該方法向響應(yīng)對(duì)象添加了一個(gè)屬性,確保新屬性也是響應(yīng)性的,從而觸發(fā)了視圖更新。

用下述實(shí)例討論該情況:

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

 

  1. el: '#app'
  2.   data: { 
  3.     person: { 
  4.       name: "David" 
  5.     }, 
  6.     activities: [ 
  7.       "Reading books"
  8.       "Listening music"
  9.       "Watching TV" 
  10.     ] 
  11.   }, 
  12.   methods: {  
  13.     // 1. Add a new property to an object 
  14.     addAgeProperty() { 
  15.       this.person.age = 30 
  16.     }, 
  17.     // 2. Setting an array item by index 
  18.     editActivity(index) { 
  19.       const newValue = prompt('Input a new value'
  20.       if (newValue) { 
  21.         this.activities[index] = newValue 
  22.       } 
  23.     }, 
  24.     // 3. Modifying the length of the array 
  25.     clearActivities() {  
  26.       this.activities.length = 0  
  27.     } 
  28.   } 
  29. }); 

在上面的示例中,我們會(huì)發(fā)現(xiàn)這三種方法都不起作用。我們不能向該person對(duì)象添加新屬性,無法使用activities的索引來編輯數(shù)組中的項(xiàng)目,也不能修改activities數(shù)組的長(zhǎng)度。

優(yōu)化如下:

  1. el: '#app'
  2.   data: { 
  3.     person: { 
  4.       name: "David" 
  5.     }, 
  6.     activities: [ 
  7.       "Reading books"
  8.       "Listening music"
  9.       "Watching TV" 
  10.     ] 
  11.   }, 
  12.   methods: {  
  13.     // 1. Adding a new property to the object 
  14.     addAgeProperty() { 
  15.       Vue.set(this.person, 'age'30
  16.     }, 
  17.     // 2. Setting an array item by index 
  18.     editActivity(index) { 
  19.       const newValue = prompt('Input a new value'
  20.       if (newValue) { 
  21.         Vue.set(this.activities, index, newValue) 
  22.       } 
  23.     }, 
  24.     // 3. Modifying the length of the array 
  25.     clearActivities() {  
  26.       this.activities.splice(0
  27.     } 
  28.   } 
  29. }); 

在此示例中,我們用Vue.setAPI方法將新age屬性添加到person對(duì)象,并從活動(dòng)數(shù)組中選擇/修改特定項(xiàng)目。在最后一種情況下,使用JavaScript內(nèi)置splice方法。

這個(gè)做法完全可行但卻略顯笨拙,而且會(huì)導(dǎo)致前后代碼不一致。而Vue 3就解決了這個(gè)問題。

我們用下面示例繼續(xù)看:

  1. data() { 
  2.     return { 
  3.       person: { 
  4.         name: "David" 
  5.       }, 
  6.       activities: [ 
  7.         "Reading books"
  8.         "Listening music"
  9.         "Watching TV" 
  10.       ] 
  11.     } 
  12.   }, 
  13.   methods: {  
  14.     // 1. Adding a new property to the object 
  15.     addAgeProperty() { 
  16.       this.person.age = 30 
  17.     }, 
  18.     // 2. Setting an array item by index 
  19.     editActivity(index) { 
  20.       const newValue = prompt('Input a new value'
  21.       if (newValue) { 
  22.         this.activities[index] = newValue 
  23.       } 
  24.     }, 
  25.     // 3. Modifying the length of the array 
  26.     clearActivities() {  
  27.       this.activities.length = 0  
  28.     } 
  29.   } 
  30.  
  31. Vue.createApp(App).mount('#app'

可以看到在Vue 3中,所有方法都可以正常工作。

在Vue 2.6中,引入的Vue.observable API方法,一定程度的公開了響應(yīng)式系統(tǒng),使開發(fā)人員可以體驗(yàn)到響應(yīng)式系統(tǒng)的內(nèi)容。實(shí)際上,這和Vue內(nèi)部用來包裝data對(duì)象是完全相同的方法,對(duì)于在簡(jiǎn)單場(chǎng)景創(chuàng)建小的跨組件狀態(tài)存儲(chǔ)很有用。但依舊沒辦法和Vue3的響應(yīng)式系統(tǒng)相比,接下來就為大家詳細(xì)介紹。

注意:由于Object.defineProperty方法是僅限ES5且不可調(diào)整的功能,因此Vue 2不支持IE8及以下版本。

Vue 3響應(yīng)式系統(tǒng)如何工作

為了充分利用ES6 Proxy and Reflect API ,Vue 3中的響應(yīng)式系統(tǒng)已被完全重寫。新版本新增響應(yīng)式API,該API使系統(tǒng)比以前更加靈活和強(qiáng)大。

Proxy API允許開發(fā)人員攔截和修改目標(biāo)對(duì)象上的更低級(jí)對(duì)象操作。代理(proxy)是對(duì)象的克隆/包裝(clone/wrapper),并提供特殊功能(稱為target),這些功能響應(yīng)特定的操作并覆蓋JavaScript對(duì)象的內(nèi)置行為(稱為traps)。如果仍然需要使用默認(rèn)行為,則可以使用相應(yīng)的Reflection API,其名稱顧名思義就是反映Proxy API的方法。這里有一個(gè)示例,用來了解如何在Vue 3中使用這些API:

  1. name: "David"
  2.   age: 27 
  3. }; 
  4.  
  5. const handler = { 
  6.   get(target, property, receiver) { 
  7.     // track(target, property) 
  8.     console.log(property) // output: name 
  9.     return Reflect.get(target, property, receiver) 
  10.   }, 
  11.   set(target, property, value, receiver) { 
  12.     // trigger(target, property) 
  13.     console.log(`${property}: ${value}`) // output: "age: 30" and "hobby: Programming" 
  14.     return Reflect.set(target, property, value, receiver) 
  15.   } 
  16.  
  17. let proxy = new Proxy(person, handler);    
  18.  
  19. console.log(person) 
  20.  
  21. // get (reading a property value) 
  22. console.log(proxy.name)  // output: David 
  23.  
  24. // set (writing to a property) 
  25. proxy.age = 30
  26.  
  27. // set (creating a new property) 
  28. proxy.hobby = "Programming"
  29.  
  30. console.log(person) 

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

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

  • target:代理包裝的目標(biāo)對(duì)象
  • property:屬性名稱
  • value:屬性值(此參數(shù)僅用于設(shè)置操作)
  • receiver:進(jìn)行操作的對(duì)象(通常是代理)
  • Reflect API方法與其相應(yīng)的代理方法接受相同的參數(shù)

注釋中track函數(shù)和trigger函數(shù)特定用于Vue,用于跟蹤何時(shí)讀取屬性以及何時(shí)修改/添加屬性。

在示例的最后一部分,用控制臺(tái)語句輸出原始person對(duì)象。然后用另一份聲明中讀取屬性name的proxy對(duì)象。接下來,修改age屬性并創(chuàng)建一個(gè)新hobby屬性。最后,再次輸出該對(duì)象以查看它是否正確更新。

以上就是Vue3響應(yīng)式系統(tǒng)的完整工作流程,但在實(shí)際工作中會(huì)復(fù)雜得多。

使用Vue 3響應(yīng)式系統(tǒng),還有一些注意事項(xiàng):

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

總結(jié)

以上我們將Vue2和Vue3中響應(yīng)式系統(tǒng)部分進(jìn)行了比較,并對(duì)響應(yīng)式系統(tǒng)的工作原理進(jìn)行了說明,在后面的文章中,我們會(huì)進(jìn)一步為大家介紹Vue3中響應(yīng)式系統(tǒng)的API,敬請(qǐng)期待。

責(zé)任編輯:張燕妮 來源: 葡萄城官網(wǎng)
相關(guān)推薦

2022-06-26 00:00:02

Vue3響應(yīng)式系統(tǒng)

2025-01-26 00:00:00

2022-03-29 09:59:58

響應(yīng)式系統(tǒng)Vue2

2022-04-03 19:27:35

Vue2響應(yīng)式系統(tǒng)

2020-06-09 11:35:30

Vue 3響應(yīng)式前端

2019-07-01 13:34:22

vue系統(tǒng)數(shù)據(jù)

2019-12-06 10:44:53

Vue 3.0響應(yīng)式系統(tǒng)前端

2021-01-22 11:47:27

Vue.js響應(yīng)式代碼

2022-04-02 09:56:41

Vue2響應(yīng)式系統(tǒng)

2022-04-14 08:46:46

響應(yīng)式系統(tǒng)js

2022-04-06 07:28:47

數(shù)組響應(yīng)式系統(tǒng)

2022-06-13 10:42:21

分布式事務(wù)數(shù)據(jù)庫

2020-03-16 10:25:49

前端React Hooks響應(yīng)式布局

2023-06-01 19:19:41

2017-08-30 17:10:43

前端JavascriptVue.js

2021-10-18 09:01:01

前端賦值淺拷貝

2022-03-31 10:15:10

分支切換響應(yīng)式系統(tǒng)

2022-08-22 09:01:24

Vue響應(yīng)式原則雙向數(shù)據(jù)綁定

2021-06-28 07:12:28

賦值淺拷貝深拷貝

2022-04-12 10:05:18

響應(yīng)式系統(tǒng)異步隊(duì)列
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)