本篇文章為大家帶來了vue2&vue3數據響應式原理分析及手動實現的相關知識,數據響應式視圖跟數據是自動更新的,數據更新的時候視圖是自動的更新的追踪數據的變化,希望對大家有幫助。
資料響應式
- 檢視跟資料是自動更新的,資料更新的時候檢視是自動的更新的
- #追蹤資料的變化,在讀取資料或設定資料的時候能夠做一些劫持的一些動作
- vue2 使用defineProperty
- vue3 改用Proxy
使用defineProperty
如何追蹤變化
var obj = {}var age Object.defineProperty(obj, 'age', { get: function() { consoel.log('get age ...') return age }, set: function(val) { console.log('set age ...') age = val }})obj.age =100 //set age ...console.log(obj.age)//get age ...
物件obj在取age屬性的時候會呼叫資料劫持的get方法
在給age屬性賦值的時候會呼叫set方法
那怎麼使用Object.defineProperty實作一個資料回應式呢
function defineReactive(data) { if (!data || Object.prototype.toString.call(data) !== '[object Object]') return; for (let key in data) { let val = data[key]; Object.defineProperty(data, key, { enumerable: true, //可枚举 configurable: true, //可配置 get: function() { track(data, key); return val; }, set: function() { trigger(val, key); }, }); if (typeof val === "object") { defineReactive(val); } }}function trigger(val, key) { console.log("sue set", val, key);}function track(val, key) { console.log("sue set", val, key);}const data = { name:'better', firends:['1','2']}defineReactive(data)console.log(data.name)console.log(data.firends[1])console.log(data.firends[0])console.log(Object.prototype.toString.call(data))
這個函數defineReactve
用來對Object.defineProperty
進行封裝,從函數名稱可以看出,運作就是定義一個響應式資料,封裝後只需要傳遞data,key和val就行
每當從data讀取key的時候觸發track函數,往data的key設定資料時,set函數中的trigger函數觸發
陣列的響應式
我們透過Array原型上的方法來改變陣列的內容不會觸發getter和setter
整理發現Array原型中可以改變陣列本身內容
的方法有7個,分別push
pop
#shift
unshift
splice
sort
reverse
vue2 改寫了這7種方法
實作方式:
以Array.propertype為原型建立一個arrayMethods物件,再使用Object.setPropertypeOf(o, arryMethods)
將o的__proto__指向arrayMethods
如何收集依賴
使用
<template><p>{{name}}</p></template>
該範本中使用資料name
, 我們要觀察資料, 當資料的屬性改變的時候, 可以通知哪些使用的地方,
這就是我們要先收集依賴,即把用到資料name的地方收集起來,然後等資料變化的時候,把之前收集好的依賴循環觸發一遍,總結來說就是getter中收集依賴,在setter中觸發依賴
使用proxy
Proxy物件用於建立一個物件的代理, 從而實現基本操作的攔截和定義(如屬性查找、賦值、枚舉、函數掉用等)
const p = new Proxy(target, handler)
target
要使用
Proxy
包裝的目標物件(可以是任何類型的對象,包括原生數組,函數,甚至另一個代理) 。handler
一個通常以函數為屬性的對象,各屬性中的函數分別定義了在執行各種操作時代理
p
的行為。
reflect是內建對象, 他提供攔截javascript操作的方法, 這些方法和Proxy handlers相同
Reflect.set將值分配給屬性的函數。傳回一個Boolean 如果更新成功則回傳true
Reflect.get取得物件身上某個屬性的值,類似target[name]
如何實作劫持
const dinner = { meal:'111'}const handler = { get(target, prop) { console.log('get...', prop) return Reflect.get(...arguments) }, set(target, key, value) { console.log('get...', prop) console.log('set',key,value) return Reflect.set(...arguments) }}const proxy = new Proxy(dinner, handler)console.log(proxy.meal)console.log(proxy.meal)
程式碼中dinner 物件代理到handler上
跟defineProperty
區別defineProperty
的屬性需要遍歷才能監管所有屬性
使用proxy可以將物件所有屬性進行代理
用proxy實作一個模擬響應式
function reactive(obj) { const handler = { get(target, prop, receiver) { track(target, prop); const value = Reflect.get(...arguments); if(typeof value === 'Object') { reactive(value) }else { return value } }, set(target,key, value, receiver) { trigger(target,key, value); return Reflect.set(...arguments); }, }; return new Proxy(obj,handler)}function track(data, key) { console.log("sue set", data, key);}function trigger(data, key,value) { console.log("sue set", key,':',value);}const dinner = { name:'haochi1'}const proxy =reactive(dinner)proxy.name proxy.list = []proxy.list.push(1)
執行後自動列印
#思考:為啥只在get中使用遞歸,set不使用呢?
賦值也需要先get
#簡單總結:
- #vue2 (淺響應式)
- 遍歷data,使用defineProperty攔截所有屬性
- 當使用者操作檢視,會觸發set攔截器
- set先改變目前資料, 再通知wartch, 讓watch去通知檢視更新
- 檢視重繪, 再次從get中取得對應的資料
- vue3 (深度回應式) :
使用proxy 進行代理;攔截data任意屬性的任意操作(13種), 包括屬性的讀寫, 屬性的添加, 屬性的刪除等等
使用Reflect進行反射;動態對被代理的物件的對應屬性進行特定的操作
代理物件(proxy)的反射物件(reflect)必須相互配合才能實現響應式
兩者的不同
Proxy能劫持整個物件,而Object.defineProperty只能劫持物件的屬性; 前者遞歸回傳屬性對應的值的代理即可實現響應式,後者需要深度遍歷每個屬性,後者對數組的操作很不友好.
更多編程相關知識,請訪問:編程入門! !
以上是vue2&vue3資料響應式原理分析及手動實作(實例詳解)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

前端有没有现成的库,可以直接用来绘制 Flowable 流程图的?下面本篇文章就跟小伙伴们介绍一下这两个可以绘制 Flowable 流程图的前端库。

vue不是前端css框架,而是前端JavaScript框架。Vue是一套用于构建用户界面的渐进式JS框架,是基于MVVM设计模式的前端框架,且专注于View层。Vue.js的优点:1、体积小;2、基于虚拟DOM,有更高的运行效率;3、双向数据绑定,让开发者不用再去操作DOM对象,把更多的精力投入到业务逻辑上;4、生态丰富、学习成本低。

Vue3如何更好地使用qrcodejs生成二维码并添加文字描述?下面本篇文章给大家介绍一下Vue3+qrcodejs生成二维码并添加文字描述,希望对大家有所帮助。

本篇文章我们来了解 Vue2.X 响应式原理,然后我们来实现一个 vue 响应式原理(写的内容简单)实现步骤和注释写的很清晰,大家有兴趣可以耐心观看,希望对大家有所帮助!


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

Dreamweaver Mac版
視覺化網頁開發工具

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

記事本++7.3.1
好用且免費的程式碼編輯器