How to implement two-way data binding (interview questions)

How to implement two-way data binding (interview questions)

There are two ways to implement two-way binding:

  1. Object.definedProperty( ) [Object.definedProperty( ) used by vue2 for object monitoring]
  2. Proxy (proxy object) [After vue3, use Proxy to achieve]

To achieve through the above two methods, in simple terms, it is the hijacking of data. When accessing or modifying the properties of an object, it is intercepted through these two methods, and then further operation returns the result.

1. Use Object.defineProperty() to realize two-way data binding:

  • Data -> view Object.defineProperty hijacks the value change of the object property, and affects the view in the set method
  • View -> data monitoring input/change event, assign value to variable
<body>
    <div class="box">
        <h4>当控制台中的值发生改变,input框中的内容随之发生改变</h4>
        数据影响视图:
        <input type="text" id="inp">
    </div>

    <div class="box">
        <h4>当input框中内容发生改变,控制台中的值发生改变</h4>
        视图影响数据:
        <input type="text" id="inp2">
    </div>

    <script>
        // data对象
        let data = {
      
      
            msg: '初始值'
        }

        //definedProperty()方法  vue2 

        // txt 实例
        let txt = {
      
      };
        let txt1 = {
      
      };

        // 1. 变量  =》 视图   使用Object.definedProperty定义对象中新属性或修改原有的属性(也就是检测对象属性值的变化)
        // ----Object.definedProperty语法
        // -------defineProperty(属性所在对象,属性名,描述符对象(value))

        // (1):给txt添加同名的属性(影子)
        Object.defineProperty(txt, 'msg', {
      
      
            set(val) {
      
       //给txt的msg属性赋值,就会触发set方法(val就是给txt.msg赋予的值)
                data['msg'] = val;
                // (2): set中影响对应视图
                document.getElementById('inp').value = val;
            },
            get() {
      
       //获取txt的msg的值
                return data['msg']
            }
        })

        // // 2. 视图  =》  变量  (依赖于oninput/onchange事件)
        inp2.oninput = function() {
      
      
            txt1.msg = this.value
        }

    </script>
</body>

image.png

Two-way data binding (definedProperty)

2. Use Proxy (proxy) to realize data two-way binding:

  • Create a proxy object for the object and modify the method of the proxy object
<body>
    <div class="box">
        <h4>当控制台中的值发生改变,input框中的内容随之发生改变</h4>
        数据影响视图:
        <input type="text" id="inp">
    </div>

    <div class="box">
        <h4>当input框中内容发生改变,控制台中的值发生改变</h4>
        视图影响数据:
        <input type="text" id="inp2">
    </div>

    <script>
        // data对象
        let data = {
      
      
            msg: '初始值'
        }

        // Proxy(代理对象) vue3
        let txt = new Proxy(data, {
      
      
            set: function(target, prop, val) {
      
      
                data['msg'] = val;
                document.getElementById('inp').value = val;
                return Reflect.set(target, prop, val);
            },
            get: function(target, prop) {
      
      
                return Reflect.get(target, prop);
            }
        })

        let txt1 = new Proxy(data, {
      
      
            set: function(target, prop, val) {
      
      
                data['msg'] = val;
                return Reflect.set(target, prop, val)
            },
            get: function(target, prop) {
      
      
                return Reflect.get(target, prop)
            }
        })

        inp2.oninput = function() {
      
      
            txt1.msg = this.value;
        }
    </script>
</body>

image.png

Two-way data binding (Proxy)

3. The difference between Object.definedProperty( ) and Proxy (proxy)

(1) Proxy is much more convenient to use than Object.defineProperty.

(2) Proxy proxies the entire object, and Object.defineProperty only proxies a property on the object.

(3) In vue, Proxy is recursive when called, Object.defineProperty is all recursive at the beginning, Proxy performance is better than Object.defineProperty.

(4) When a new property is defined on an object, Proxy can monitor it, but Object.defineProperty cannot.

(5) When the array is added, deleted or modified, Proxy can monitor it, but Object.defineProperty cannot.

(6) Proxy is not compatible with IE, and Object.defineProperty is not compatible with IE8 and below.

4. Summary:

(1) How to synchronize view changes to variables?

  • The view binds the oninput/onchange event, gets the value and assigns it to the variable

(2) How to detect the value change of the attribute in the object?

  • Object.defineProperty data hijacking, rewriting set and get

(3) When are set and get triggered?

  • Assigning a value to a property triggers a set, and taking a value triggers a get

Guess you like

Origin blog.csdn.net/SH744/article/details/126999990