This article brings you the relevant knowledge of vue2&vue3 data responsiveness principle analysis and manual implementation. The data responsive view and data are automatically updated. When the data is updated, the view is automatically updated to track the changes in the data. I hope everyone has to help.
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 ...
The object obj will call the get method of data hijacking when getting the age attribute
When assigning a value to the age attribute, the set method will be called
How to use Object.defineProperty to implement a data response?
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))
This function defineReactve
is used to encapsulate Object.defineProperty
. From the function name, you can It can be seen that the function is to define a responsive data. After encapsulation, you only need to pass the data, key and val
The track function is triggered whenever the key is read from the data, and when the data is set to the key of the data, set The trigger function in the function triggers
We change the content of the array through the method on the Array prototype and it will not trigger the getter and setter
After sorting it out, we found that it can be done in the Array prototypeThere are 7 methods to change the content of the array itself
, respectively push
pop
shift
unshift
splice
sort
reverse
vue2 rewrites these 7 methods
Implementation method:
Create an arrayMethods object based on Array.propertype as the prototype, and then use Object.setPropertypeOf(o, arryMethods)
Point o's __proto__ to arrayMethods
Use
<template><p>{{name}}</p></template>
Data used in this templatename
, we need to observe the data, when the properties of the data change, we can notify the places where it is used,
This is why we need to collect dependencies first, that is, use Collect it at the data name, and then when the data changes, trigger the previously collected dependency loop. In summary, it is to collect dependencies in the getter and trigger the dependencies in the setter
Proxy object is used to create a proxy for an object, thereby realizing the interception and definition of basic operations (such as attribute search, assignment, enumeration, function deactivation, etc.)
const p = new Proxy(target, handler)
target
The target object to be wrapped with Proxy
(can be any type of object, including a native array, a function, or even another proxy) .
handler
An object that usually has functions as attributes. The functions in each attribute are respectively defined during execution. The behavior of p
during various operations.
reflect is a built-in object that provides methods to intercept JavaScript operations. These methods are the same as Proxy handlers
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)
The difference between
defineProperty
defineProperty's properties need to be traversed to supervise all properties
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)
Introduction to Programming! !
The above is the detailed content of Vue2&vue3 data responsive principle analysis and manual implementation (detailed examples). For more information, please follow other related articles on the PHP Chinese website!