Two way binding with Proxy

We need to use Proxy to implement two-way binding in vue3.0, so let's try to implement it first. 1 implementation of object.definepropertyThe ori...

We need to use Proxy to implement two-way binding in vue3.0, so let's try to implement it first.

1 implementation of object.defineproperty
The original implementation of vue2 uses Object.defineProperty to listen to set, but it can't listen to the set value of array directly subscript.

function observe(data) { if (!data || typeof data !== 'object') { return; } // Take out all attribute traversal Object.keys(data).forEach(function(key) { defineReactive(data, key, data[key]); }); }; function defineReactive(data, key, val) { observe(val); // Listen to child properties Object.defineProperty(data, key, { enumerable: true, // enumerable configurable: false, // defineProperty can no longer be overridden get: function() { return val; }, set: function(newVal) { console.log('-------Notify subscribers--------') val = newVal; } }); }

2 implement with Proxy

The main principle of using Proxy is to use a new Proxy object to Proxy your data value. It should be noted that for array method operations, there will be two assignment operations, one is to add a value, the other is to change its length value. For array subscripts that cannot be monitored by Object.defineProperty, the Proxy can monitor.

function observe(data) { if (!data || typeof data !== 'object') { return; } // Take out all attribute traversal Object.keys(data).forEach(function(_k) { // Proxy does not allow binding on non object if (data[_k] && typeof data[_k] === 'object') { data[_k] = defineReactive(data[_k]); } }); } function defineReactive(data) { return new Proxy(data, { set(target, key, value, proxy) { // During array operation, the data will be set twice, the data will be changed once, the length will be changed once, and the data value will be changed twice, so the message should not be distributed once more if ( Object.prototype.toString.call(data) === "[object Array]" && key === "length" ) { Reflect.set(target, key, value, proxy); return true; } observe(data); Reflect.set(target, key, value, proxy); console.log('-------Notify subscribers--------') return true; } });

2 December 2019, 14:54 | Views: 7569

Add new comment

For adding a comment, please log in
or create account

0 comments