zoukankan      html  css  js  c++  java
  • Vue中如何实现响应式的?v-model实现原理?

      用过vue的都知道,vue中data中定义的数据会随着我们通过方法改变该数据的同时,页面上相关此数据的也会相应的刷新,实现响应式数据。它是如何实现这一功能的?

    Vue2.xx版本中用Object.defineProperty(obj, prop, descriptor) 

      可传入三个值,其作用是该方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

        第一个值传入要修改的对象
        第二个值传入该对象中要修改的key
        第三个值是一个对象,里面有set 和get两种方法 set为值发生修改是所做的操作 get为读取改值时的操作。

      简单实现的代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <script src="../js/vue.js"></script>
    </head>
    <body>
      <input type="text">
      <p></p>
      <script>
      var obj = {}
      var temp = null
      document.querySelector('input').oninput =function(){
        //当我们设置obj中的a属性的值时,会触发set方法,接收到新的值,我们将文本框中的值赋给a属性
        obj.a = this.value     
    //当我们获取obj中的a属性的值时,会触发get方法,返回新的值,我们将获取到的新值显示在网页的p标签中
        document.querySelector('p).innerHTML = obj.a   }   Object.defineProperty(obj,
    'a',{     get:function(){
          console.log('获取到新值在p标签中显示')       
    return temp     },     set:function(val){       temp = val
          console.log('监听到了a属性的值在改变')     }   })
    </script> </body> </html>

    Vue3.xx版本利用ES6中的Proxy

      Vue2.xx版本中的数据双向绑定有如下缺点:

        1. 监听数组的方法不能触发Object.defineProperty方法中的set操作(如果要监听的到话,需要重新编写数组的方法)。

        2. 必须遍历每个对象的每个属性,如果对象嵌套很深的话,需要使用递归调用。Proxy更好的解决如上面的问题。

      当外界每次对obj进行操作时,就会执行handler对象上的一些方法。

      handler中常用的对象方法如下:

        1. get(target, propKey, receiver)

          该方法的含义是:用于拦截某个属性的读取操作。它有三个参数,如下解析:

          target: 目标对象

          propKey: 目标对象的属性

          receiver: (可选),该参数为上下文this对象

        2. set(target, propKey, value, receiver)

          该方法是用来拦截某个属性的赋值操作,它可以接受四个参数,参数解析分别如下:

          target: 目标对象

          propKey: 目标对象的属性名

          value: 属性值

          receiver(可选): 一般情况下是Proxy实列

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    <body>
      <input type="text">
      <p></p>
    </body>
    <script>
    var target={
      msg:null
    }
    document.querySelector('input').oninput=function(){
      obj.msg=this.value
      document.querySelector('p').innerHTML=obj.msg
    }
    var handler={
      get:function(target,property){
        return target[property];
      },
      set:function(target,property,value){
        target[property]= value
      }
    }
    var obj=new Proxy(target,handler)
    </script>
    </html>
  • 相关阅读:
    【C#】枚举和字符串以及数字之间的互相转换
    MySQL中int(M)和tinyint(M)数值类型中M值的意义
    C# 将数组拼接为字符串 string.Join 的使用
    MySQL-locate()函数
    C# 4.0 dynamic用法,并且与 var, object的区别
    Go语言 go get 找不到 google.golang.org/protobuf/encoding/prototext 解决办法
    Go语言 中逗号ok模式
    MySQL数据库面试题(2020最新版)
    .Net Core 3.0开源可视化设计CMS内容管理系统建站系统
    SQL Server 全文搜索/全文索引
  • 原文地址:https://www.cnblogs.com/cqweb/p/14225803.html
Copyright © 2011-2022 走看看