欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Vue的双向数据绑定原理--简单案例直接get到

程序员文章站 2022-07-12 21:56:46
...


前言

虽然写项目的话可能会用不着,但要是面试的话会问哪
提问: Vue 中双向数据绑定是如何实现的? ||
关键词:“代理”、“Object.defineProperty(vue2)”、“Proxy(vue3)”
核心:数据订阅、数据劫持(代理)


一、实现方法和原理

  • Object.defineProperty(vue2)和 Proxy(vue3)
    • 不同点
      • vue2中实现双向绑定的原理,采用的是es5中的Object.defineProperty这个方法来实现的
      • 在vue3中则是采用Proxy这个对象来实现的
    • 相同点
      • 虽然说两者实现的方法是不一样的,但是在流程上,包括含义上是非常像的。都是通过代理的方式来实现双向数据绑定
  • (以vue2为例)当把一个普通的JavaScript对象传给Vue实例的data选项,Vue将遍历此对象所有的属性,使用Object.defineProperty把这些属性全部转为getter(获取)/setter(设置)。(getter和setter相当于两个代理,一个代理我们获取数据,另一个代理我们设置数据)

二、 示例

// es5中提供的方法
Object.defineProperty(obj, prop, descriptor)
// 方法会直接在一个对象(obj)上定义一个新属性,或者修改一个对象的现有属性(prop),并返回此对象。
// 应当直接在Object构造器对象上调用此方法,而不是在任意一个Object类型的实例上调用。
  • 这个方法有三个参数

obj
要定义属性的对象。
prop
要定义或修改的属性的名称 。
descriptor
如何定义或修改这属性
要定义的选项,“{ }”。在这里面设置getter和setter。

  • 实例(以es5为例)
<div id="app">
        <div>
            <input type="text" id="ipt" oninput="changeData(this)">
        </div>
        <div>
            <div id="main"></div>
        </div>
    </div>
    <script>
        // 1、数据初始化,等同与vue中的data属性
        var data ={
            msg:"数据的双向绑定"
        }
        // 2、显示页面上的数据(原生js)
        document.getElementById("ipt").value = data.msg
        document.getElementById("main").innerText = data.msg
       
        // 3、产生双向数据绑定需要的代理
        // 采用obj.msg代理data.msg 当获取obj.msg时实质上是获取data.msg, 设置obj.msg实质上是设置data.msg
        var obj={}
        Object.defineProperty(obj,'msg',{
            // 产生getter(代理获取者)和setter(代理设置者)
            get:function(){
                // 获取obj.msg时实质上是获取data.msg
                return data.msg
            },
            // 形参val是需要设置给data.msg的值
            set:function(val){
                // 设置obj.msg实质上是设置data.msg
                data.msg = val
                // 判断程序是否走了set ,输出data
                console.log(data.msg);
            }
        })
        // 4、input事件的处理程序
        function changeData(a){
            // 调用代理去设置数据
            obj.msg= a.value
            // 更新下方div的显示
            document.getElementById("main").innerText = obj.msg
        }
    </script>
  • 流程梳理
    • 执行input输入时,触发input事件
    • 触发事件后在走obj.msg=a.value (原来obj中没有msg)
    • 后触发 Object.defineProperty(obj,‘msg’,{})定义一个msg
    • 当input事件改变obj.msg时 程序走 其代理方法中的get (执行get时给data.msg赋值,此时参数val为a.value) 当获取obj.msg中的值时,程序走set(而set执行后返回的是data.msg)