Cet article vous apporte les connaissances pertinentes sur l'analyse du principe de réponse aux données vue2 et vue3 et la mise en œuvre manuelle. La vue et les données réactives aux données sont automatiquement mises à jour lorsque les données sont mises à jour, la vue est automatiquement mise à jour pour suivre les modifications des données. vous sera utile. Tout le monde est utile.
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 ...
L'objet obj appellera la méthode get de piratage de données lors de l'obtention de l'attribut age
Lors de l'attribution d'une valeur à l'attribut age, appelez le set method
Ensuite, comment utiliser Object.defineProperty pour implémenter une réponse de données
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))
Cette fonction defineReactve
est utilisée pour encapsuler Object.defineProperty
À partir du nom de la fonction, vous. On peut voir que la fonction consiste à définir des données réactives. Après l'encapsulation, il vous suffit de transmettre les données, la clé et la valeurdefineReactve
用来对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对象用于创建一个对象的代理, 从而实现基本操作的拦截和定义(如属性查找、赋值、枚举、函数掉用等)
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
Chaque fois que la clé est lue à partir des données, la fonction de suivi est déclenchée et lorsque les données sont définies. à la clé des données, dans la fonction set La fonction trigger déclenche la
réactivité du tableau
Nous modifions le contenu du tableau via les méthodes sur le prototype Array, qui ne déclencheront pas le getter et le setter
Après. organiser et découvrir les méthodes dans le prototype Array qui peuventchanger le contenu du tableau lui-même
Il y en a respectivement 7 push
pop
shift
unshift
splice
sort <code>reverse
vue2 réécrit ces 7 méthodes
Méthode d'implémentation : Créer un tableauMethods objet avec Array.propertype comme prototype, puis utilisez Object.setPropertypeOf(o, arryMethods)Pointez le __proto__ de o vers arrayMethods<img src="https://img.php.cn/upload/article/000/000/067/acd642f4f02e97980836bd636302ac44-1.png" alt="Analyse du principe de réactivité aux données Vue2 et Vue3 et mise en œuvre manuelle (exemples détaillés)">
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)
nom
sont utilisées dans ce modèle. Nous devons observer les données. Lorsque les attributs des données changent, nous pouvons notifier les endroits où elles sont utilisées,target code><li>
<li>L'objet cible à envelopper avec <code> Proxy
(peut être n'importe quel type d'objet, y compris un tableau natif, une fonction ou même un autre proxy).
handler
Un objet généralement avec des fonctions comme attributs. Les fonctions de chaque attribut définissent respectivement le comportement de l'agent p
lors de l'exécution de diverses opérations.
defineProperty
defineProperty
doivent être parcourues pour superviser toutes les propriétésUtilisez un proxy pour proxy toutes les propriétés de l'objetUtilisez un proxy pour implémenter une réponse simuléerrreee
Imprimer automatiquement après l'exécution🎜 🎜🎜🎜🎜Réflexion : Pourquoi utiliser uniquement la récursivité dans get et non set 🎜🎜L'affectation doit également être obtenue en premier🎜🎜Résumé simple : 🎜🎜🎜vue2 (shallow responsive)🎜🎜 🎜🎜Traverser les données et utiliser DefineProperty Intercepter tous les attributs🎜🎜Lorsque l'utilisateur exploite la vue, l'intercepteur défini sera déclenché🎜🎜set modifie d'abord les données actuelles, puis notifie la montre, laissant la montre notifier la mise à jour de la vue🎜🎜View redessinez et obtenez à nouveau les données correspondantes auprès de get🎜🎜🎜 🎜vue3 (réactivité profonde) : 🎜🎜🎜🎜🎜Utilisez un proxy pour un proxy ; interceptez toute opération sur n'importe quel attribut de données (13 types), y compris la lecture et l'écriture d'attributs, ajouter des attributs, supprimer des attributs, etc. 🎜🎜🎜🎜 utiliser Reflect effectue une réflexion ; effectue dynamiquement des opérations spécifiques sur les propriétés correspondantes de l'objet proxy🎜🎜🎜🎜L'objet de réflexion (reflect) de l'objet proxy (proxy) doit coopérer avec chacun autre pour atteindre la réactivité🎜🎜🎜🎜La différence entre les deux🎜🎜Proxy Il peut détourner l'objet entier, tandis que Object.defineProperty ne peut détourner que les propriétés de l'objet, le premier peut atteindre la réactivité en renvoyant récursivement le proxy de la valeur correspondante ; à la propriété, alors que cette dernière nécessite une traversée approfondie de chaque propriété, et cette dernière est très peu conviviale pour les opérations sur les tableaux. 🎜🎜Pour plus de connaissances sur la programmation, veuillez visiter : 🎜Introduction à la programmation🎜 ! ! 🎜Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!