vue-双向绑定原理

1.双向绑定

[1]定义

  • 在视图上的数据发生了变化,data中的数据也要对应改变;
  • data中的数据发生了变化,视图上的数据也要对应改变;

[2]原理

vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;

2.vue2.0双向绑定实现

在vue2.x中数据双向绑定的核心是使用 Object.defineProperty(对象,key,{get(),set()})方法来给对象的属性添加get/set方法实现的!

  • 当我们获取对象中该属性 的数据时,就会调用该属性的get方法
  •  <script>
          // vue2.x双向绑定核心是通过Object.defineProperty()方法实现
          let data = {
            name: 'chaochao'
          }
          Object.defineProperty(data, 'name', {
            get () {
              console.log('我是get')
            },
            set () {}
          })
          data.name // 在此处获取了data的name属性值,就会调用name属性的get方法
        </script>

     注:此时还存咋一个问题,因为我们获取data.name时调用get希望 get方法返回给我们 该属性值也就是说 data.name ; 但是若是return data.name会在此调用get方法; 递归  却没有递归边界---死循环

  • <script>
          // vue2.x双向绑定核心是通过Object.defineProperty()方法实现
          let data = {
            name: 'chaochao'
          }
          let _name = data.name
          Object.defineProperty(data, 'name', {
            get () {
              // return data.name
              // 此处造成死循环 ---解决先赋值
              return _name
            },
            set (str) {
              console.log(str)
            }
          })
          console.log(data.name) // 'chaochao'
        </script>

     

  • 当我们修改对象该属性的数据时,就会调用该属性的set方法;set方法形参接收的值就是该属性修改后的值!
  •  <script>
          // vue2.x双向绑定核心是通过Object.defineProperty()方法实现
          let data = {
            name: 'chaochao'
          }
          Object.defineProperty(data, 'name', {
            get () {
              console.log('我是get')
            },
            set (str) {
              console.log(str) // set方法有一个形参,形参接收的值就是修改之后的值----'niuniu'
            }
          })
          data.name = 'niuniu' // 在此处我们修改的data对象name属性值,就会调用name属性的set方法;
        </script>

     

  • 使用js模拟vue的双向绑定
  •  <body>
        <h3 id="h3Box"></h3>
        <input type="text" id="inputBox" />
        <script>
          let data = {
            name: 'chaochao'
          }
          let _name = data.name
          Object.defineProperty(data, 'name', {
            get () {
              return _name
            },
            set (str) {
              _name = str
              // 2.data中数据修改会走这里---data数据修改,视图中的数据也进行修改
              document.getElementById('inputBox').value = str
              document.getElementById('h3Box').innerHTML = str
              console.log(str)
            }
          })
          // 1.dom元素值改变事件---视图中数据进性修改,data数据也进行修改
          document.getElementById('inputBox').oninput = function (e) {
            data.name = e.target.value
          }
        </script>
      </body>

     

[1]vue2.0版本中双向绑定的缺点

我们只能给对象中已经存在的属性添加绑定事件!

2.vue3.0版本双向绑定实现

在vue2.x中数据双向绑定的核心是使用new Proxy(对象,{get(),set()})方法来给对象的属性添加get/set方法实现的!

语法:new Proxy(对象,{get(对象,key){},set(对象,key,value){}})

  • 此时,data对象中所有的属性都有get和set方法了!
  •   <script>
          let data = {
            name: 'chaochao',
            sex: '18'
          }
          data = new Proxy(data, {
            get (data, key) {},
            set (data, key, value) {}
          })
          console.log(data)
        </script>

     

  • 当我们获取对象中该属性 的数据时,就会调用该属性的get方法 (不会造成死循环了;,没有使用点语法)
  •  <script>
          let data = {
            name: 'chaochao',
            sex: '18'
          }
          data = new Proxy(data, {
            get (data, key) {
              return data[key]
            },
            set (data, key, value) {}
          })
          console.log(data.name) // 此时获取name属性,调用name属性的get方法
        </script>

     

  • 当我们修改对象该属性的数据时,就会调用该属性的set方法;set方法形参接收的值就是该属性修改后的值!
  •    <script>
          let data = {
            name: 'chaochao',
            sex: '18'
          }
          data = new Proxy(data, {
            get (data, key) {
              return data[key]
            },
            set (data, key, value) {
              if (key == 'name') {
                // 如果是name属性改变
                console.log('name')
              } else {
                console.log('sex') //sex
              }
            }
          })
          data.sex = '女' // 此时修改的是sex属性,调用sex属性的set方法
        </script>
  • 使用js模拟vue的双向绑定
  •  
     <body>
        <h3 id="h3Box"></h3>
        <input type="text" id="inputBox" />
        <script>
          let data = {
            name: 'chaochao',
            sex: '18'
          }
          data = new Proxy(data, {
            get (data, key) {
              return data[key]
            },
            // data中的数据修改了,视图中的数据也要修改
            set (data, key, value) {
              if (key == 'name') {
                document.getElementById('inputBox').value = value
                document.getElementById('h3Box').innerHTML = value
              } else {
                console.log('sex') //sex
              }
            }
          })
          // 当试图数据修改,data中的数据也要修改
          document.getElementById('inputBox').oninput = function (e) {
            data.name = e.target.value
          }
        </script>
      </body>

     

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页

打赏作者

乖女子@@@

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值