精华内容
下载资源
问答
  • 本篇文章主要介绍了详解Vue双向数据绑定原理解析 ,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 所以最近攻读了其源码的一部分,先把双向数据绑定这一块的内容给整理一下,也算是一种学习的反刍。 本篇文章的Vue源码版本为v2.2.0开发版。 Vue源码的整体架构无非是初始化Vue对象,挂载数据data/props等,在不同的...
  • 首先说一下数据双向绑定原理 vue.js是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图。 实现...

    首先说一下数据双向绑定原理
    vue.js是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图。

    实现一个简单的数据双向绑定的html页面需要引入四个重要的js(四个步骤)来实现

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>MVVM</title>
    </head>
    <body>
    <div id="app">
        <p>{{msg}}</p><!--w0==> dep0  -->
        <p v-text="msg"></p><!--w1 ==> dep0-->
        <p v-html="msg"></p><!--w2 ==> dep0-->
        <!--dep0 ==>[w0,w1,w2]-->
    
    
        <p>{{friend.name}}</p><!--w3 ==> {dep1,dep2}-->
        <!--dep1==>[w3]-->
        <!--dep2==>[w3]-->
        <button v-on:click="update">更新</button>
    </div>
    <script src="./mvvm-master/js/observer.js"></script>
    <script src="./mvvm-master/js/compile.js"></script>
    <script src="./mvvm-master/js/watcher.js"></script>
    <script src="./mvvm-master/js/mvvm.js"></script>
    <script>
        const vm = new MVVM({
            el: "#app",
            data: {
                msg: "aa",//dep0
                friend:{//dep1
                    name:"cc"//dep2
                }
            },
            methods:{
                update(){
    //                this.msg = "cc";
                    this.friend.name = "dd";
                }
            }
        });
    
        console.log(vm.name)
    
    </script>
    </body>
    </html>
    

    具体步骤:
    第一步:
    observer.js源码分析

    第二步:
    compile.js源码分析

    第三步:
    watcher.js源码分析

    第四步:
    mvvm.js源码分析

    展开全文
  • proxy方法 ...可查看Vue 2.0双向绑定原理的实现 具体实现过程的代码如下: 1、定义构造函数 function Vue(option){ this.$el = document.querySelector(option.el); //获取挂载节点 this.$data =
  • 先声明,该代码是网上一位大佬提供的,但是学习它的代码过程中...该压缩文件内容是vue数据双向绑定的实现与原理解析,提供核心完整代码,并有我的代码注释,浅显易懂,但是需要es6的学习和有一定的javascript基础才行。
  • MVVM框架实现了数据双向绑定 - 当M层数据进行修改时,VM层会检测到变化,并且通知V层进行相应得修改 - 修改V层则会通知M层数据进行修改 - MVVM框架实现了视图与模型层得相互解耦 几种双向数据绑定的方式 发布.....

    MVVM框架介绍

    • M (Model,数据模型层)

    • V (View,视图层,数据展示,html页面)

    • VM (ViewModel,视图模型,V与M连接的桥梁)

    • MVVM框架实现了数据的双向绑定
      - 当M层数据进行修改时,VM层会检测到变化,并且通知V层进行相应得修改
      - 修改V层则会通知M层数据进行修改
      - MVVM框架实现了视图与模型层得相互解耦

    几种双向数据绑定的方式

    • 发布-订阅者模式,也叫观察者模式(backbone.js)
      - 它定义了一种一对多的依赖关系,即当一个对象的状态发生改变的时候,所有依赖于它的对象都会得到通知并自动更新,解决了主体对象与观察者之间功能的耦合。
      - 一般通过pub、sub的方式来实现数据和视图的绑定,但是用起来比较麻烦

      举例: 微信公众号
      订阅者: 只需要订阅微信公众号
      发布者(公众号): 发布新文章的时候,推送给所有订阅者
      优点:

      1. 解耦合
      2. 订阅者不用每次去查看公众号是否有新的文章
      3. 发布者不用关心谁订阅了它,只要给所有订阅者推送即可
    • 脏值检查(angular.js)
      - angular.js 是通过脏值检测的方式比对数据是否有变更,来决定是否更新视图。类似于通过定时器轮训检测数据是否发生了改变
    • 数据劫持
      - vue.js 则是采用数据劫持结合发布者-订阅者模式的方式。通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
      - Object.defineProperty不兼容IE8及以下的版本,所以vuejs不兼容ie8
      在这里插入图片描述

    实现双向绑定需要三个模块

    首先建立vue实例,此页代码仅演示文本节点的双向绑定

    class Vue {
      constructor(option = {}) {
        this.$el = option.el
        this.$data = option.data
    
        new Observer(this.$data)  //数据劫持用,单纯渲染页面不用此行代码
        this.proxy(this.$data) 	// 最后第4步看此行代码
        if (this.$el) new Compile(this.$el, this)
      }
    
      proxy(data) {  // 最后第4步看此方法
        Object.keys(data).forEach(key => {
          console.log(this)
          
          Object.defineProperty(this, key, {
            enumerable: true,
            configurable: true,
            get() {
              return data[key]
            },
            set(newValue) {
              if (data[key] == newValue) {
                return
              }
              data[key] = newValue
            }
          })
        })
      }
    }
    
    1. Compile

    编译模块,实现data数据渲染至视图上,methods方法可以触发
    解读:
    (1)创建Vue构造函数,添加el,data,methods方法;
    (2)获取el DOM对象下的全部子节点,放入内存中, 放入内存的dom节点为fragment碎片,但不存在与dom树中,由document.createDocumentFragment()创建,遍历fragment存放的节点,利用正则等表达式匹配并替换data数据,重新更新fragment的dom元素,并一起放进真实的dom树。这样做仅一次 重绘回流 即可渲染页面,大大减少了浏览器的负载,优化性能。代码如下

    //编译模块
    class Compile {
      constructor(el, vm) {
        this.el = typeof el === 'string'? document.getElementById('app'): el
        this.vm = vm
    
        if (this.el) {
          let fragment = this.nodeTfragment(this.el) //把所有节点放进fragment
    
          this.compile(fragment)
          this.el.appendChild(fragment)
        }
      }
    
      nodeTfragment(node) {
        let fragment = document.createDocumentFragment() //建立文档碎片
        let childNodes = [].slice.call(node.childNodes)  //[].slice.call 类数组用这一行代码转换成数组
    
        childNodes.forEach(element => {
          fragment.appendChild(element)
        });
        return fragment
      }
    
      compile(fragment) {
        let childNodes = [].slice.call(fragment.childNodes)
        childNodes.forEach( node => {
          if (node.nodeType === 3) {   //如果是文本节点
            let txt = node.textContent
            let reg = /\{\{(.+)\}\}/
    
            if (reg.test(txt)) {
              let expr = RegExp.$1  //取正则的第一组,也就是第一个出现的一对括号
              node.textContent = txt.replace(reg, this.vm.$data[expr])
    
              new Watch (this.vm, expr, newValue => {  //对每一个数据订阅 添加观察者
                node.textContent = txt.replace(reg, newValue)
              })
            }
          }
        })
      }
    }
    
    1. Observer

    劫持数据模块劫持数据模块
    解读:
    遍历数据添加劫持方法

    //数据劫持
    class Observer {
      constructor(data) {
        this.data = data
        this.walk(data)  //核心方法
      }
    
      walk(data) {
        if (!data || typeof data != 'object') return
        Object.keys(data).forEach(key => {
    
          let dep = new Dep() //此行代码请参考第3步
          let value = data[key]
          Object.defineProperty(data, key, {
            enumerable: true,
            configurable: true,
            get() {
              Dep.target && dep.addSub(Dep.target) //此行代码请参考第3步
              return value
            },
            set(newValue) {  //每当数据改变都要执行此方法
              if (value === newValue) return
              value = newValue
              dep.notify()  //此行代码请参考第3步,通知订阅者要改变
            }
          })
        })
      }
    }
    
    1. Watcher 用于连接 1与2 的模块

    在Compile模块为每个数据添加watcher构造函数(为订阅者模式),把各个watcher实例添加进一个数组集合,该数组称为Dep;至此,数据劫持与发布-订阅者模式结合,发布的意思为更改数据;
    即数据改变则拿到了所有的watcher,通过回调函数改变数据,数据改变后则重新渲染页面。

    //观察者(订阅者)
    class Watch {
     constructor(vm, expr, callback) {
       this.vm = vm
       this.expr = expr
       this.callback = callback
    
       Dep.target = this
       this.olderValue = vm.$data[expr]  //每当获取data数据时,都要执行Observer 模块Object.defineProperty的get方法
    
       Dep.target = null
     }
    
     updata() {
       let oldValue = this.olderValue
       let newValue = vm.$data[this.expr]
       if (oldValue != newValue) {
         this.callback(newValue) 
       }
     }
    }
    
    //订阅者的操作
    class Dep {
     constructor() {
       this.sub = []
     }
    
     addSub(watcher) {
       this.sub.push(watcher)
     }
    
     notify() {
       this.sub.forEach ((sub) => {
         sub.updata()
       })
     }
    }
    
    1. 将所有data的方法直接挂在至vm实例

    最后,通过proxy方法,利用Object.defineProperty方法依次添加至vm实例上请看第一段代码

    1. 结合下图总结
      在这里插入图片描述

    (1) 绿色线 :实例化Vue后,通过Compile去解析所有的指令,能看到页面渲染的内容
    (2)红色线:每解析一个指令,实例一个watcher,订阅数据的变化,逐个添加进Dep 构造函数的数组中
    (3)蓝色线: 再通过Observer 劫持到了数据变化,通过Dep拿到了所有的订阅者,即Watcher,通知Watcher数据发生了改变,进而触发每个Watcher的update方法,更新视图。

    此文档有些得不明白的地方请加v: zaq1312135000

    展开全文
  • 一、双向数据绑定的原理分析 双向数据绑定:建立在单向数据绑定的基础之上的,也就是在 model-->View的基础之上的。 双向数据绑定的实现过程: 在解析 v-model指令时, 给当前元素添加 input 监听 当 input的 ...

    一、双向数据绑定的原理分析

    1. 双向数据绑定:建立在单向数据绑定的基础之上的,也就是在 model-->View的基础之上的。
    2. 双向数据绑定的实现过程
    • 在解析 v-model指令时, 给当前元素添加 input 监听
    • inputvalue 发生改变时, 将最新的值赋值给当前表达式所对应的 data属性
    1. 实现双向数据绑定,核心过程如下:
       // 解析: v-model
      model: function (node, vm, exp) {
        // 实现数据的初始化显示和创建对应的watcher
        this.bind(node, vm, exp, 'model');
    
        var me = this,
          // 得到表达式的值
          val = this._getVMVal(vm, exp);
          // 给节点绑定input事件监听,输入改变的时寒
        node.addEventListener('input', function (e) {
          // 得到输入的最新值
          var newValue = e.target.value;
          // 如果没有变化,直接结束
          if (val === newValue) {
            return;
          }
          // 将最新的value保存给表达式所对应的属性
          me._setVMVal(vm, exp, newValue);
          val = newValue;
        });
      },
    
    1. _setVal()的核心实现:
    _setVMVal: function (vm, exp, value) {
        var val = vm._data;
        exp = exp.split('.');
        exp.forEach(function (k, i) {
          // 非最后一个key,更新val的值
          if (i < exp.length - 1) {
            val = val[k];
          } else {
            val[k] = value;
          }
        });
     }
    

    二、双向数据绑定的实现:

    1. 双向数据绑定
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>双向数据绑定</title>
    </head>
    <body>
        
        <div id="test">
            <input type="text" v-model="msg" />
            <p>{{ msg }}</p>
        </div>
    
    </body>
    <script type="text/javascript" src="./js/mvvm/compile.js"></script>
    <script type="text/javascript" src="js/mvvm/mvvm.js"></script>
    <script type="text/javascript" src="./js/mvvm/observer.js"></script>
    <script type="text/javascript" src="./js/mvvm/watcher.js"></script>
    <script type="text/javascript">
    
        new MVVM({
            el: "#test",
            data: {
                msg: "hahaha"
            }
        })
    
    </script>
    </html>
    
    展开全文
  • 自我评价 vue数据双向绑定原理分析和简单实现 代码总计分为三个版本,v3为最终版本 效果图 博客地址
  • 主要介绍了Vue源码学习之双向绑定,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 数据双向绑定总结 主要是v-model,当数据影响视图可以直接利用watcher的回调函数来更新视图,当视图影响数据时,定义一个setVal方法,将最新的值与keys传进去,在里面通过修改vm.$data来修改数据,从而达到视图影响...

    主要是输入框,在这里插入图片描述
    这时候我们需要创建于给setVal方法实时修改数据。在这里插入图片描述
    这里如果我们绑定的是一个对象,在这里插入图片描述
    那我们需要遍历到最底层去修改这个数据,所以取数组长度并且做一个判断,就是遍历到底的时候我给他赋值。
    这样就实现数据双向绑定了,

    数据双向绑定总结 主要是v-model,当数据影响视图可以直接利用watcher的回调函数来更新视图,当视图影响数据时,定义一个setVal方法,将最新的值与keys传进去,在里面通过修改vm.$data来修改数据,从而达到视图影响数据效果。在这里插入图片描述

    在这里插入图片描述

    实现代理,就是每次不用写this.$data.name而是直接写this.name

    一开始
    在这里插入图片描述
    这里的data指的是this.$data,故我们修改数据都要通过this. $data去获取修改
    这时,在外部可以实现一个代理,通过this指向,获取修改数据,如图

    在这里插入图片描述
    此时我们修改数据有两种方式,一种是this.$ data.name去走里面那层,一种是this.name直接走代理。相当于给this对象,也就是Vue对象添加上所有的属性方法并且进行一个监听。
    没有代理前
    在这里插入图片描述
    在这里插入图片描述
    this上是没有这些属性的。
    在这里插入图片描述
    代理后,在这里插入图片描述
    在这里插入图片描述
    而且我们的data里也有,所以才能两个都用。

    代理总结,也就是在this.$data的基础上,在Vue类外层,也添加了data里面的每个属性的监听,object.defineproperty(this,key,{get(){},set(){}})。这样就能通过this.去获取数据并且修改数据。

    全部总结

    Vue的MVVM模式,主要就是在new Vue的时候,有三个类,一个Complie,一个Observer,一个Watcher,这三个类通过Dep类进行关联。首先是Observer,实现数据监听,主要是将数据传进去,通过object.defineproperty每个属性的set方法和get方法来对数据进行监听。还有创建Dep类,通过Dep类来将所有订阅者加到一起,并且通过Dep.notify()来通过订阅者数据修改。

    接着是Complie类,它负责将一开始的数据渲染并且后续的数据修改更新视图,首先创建一个文档碎片对象,并将所有的节点放进去,接着通过判断将每个节点一一进行数据更新,接着就把文档碎片对象挂载到app上面去。在进行数据更新的时候,会new Watcher,创建订阅者,在创建订阅者之初会获取data里面的值,所以会调用到get函数,在get函数里面,将订阅者一一加入到dep中,这样就实现加入订阅者的功能。接着更新数据的时候,会调用set函数,set函数中调用dep.notify()来通过wathcer修改视图,watcher调用本身的update方法,获取最新的值进行判断并且调用一开始创建wathcer时的回调函数,通过Complie类实现视图更新。

    接着要实现双向数据绑定,主要是model即输入框,创建setVal方法,通过事件绑定input,获取事件对象e.target.value获取视图上输入的值,并且通过setVal进行更新,达到更新数据的功能。

    最后是代理,一开始我们的数据是在this.$data里面坚挺的,所以可以在Vue类里面,定义一个方法,在Vue类上就对这些数据进行一个监听,也是通过object.defineproperty,将第一个参数指向Vue类,遍历每个属性,并为其监听,这样在Vue类上就有这些数据和这些数据的get,set方法,并且可以通过this.name去获取或者修改数据了。

    展开全文
  • 主要给大家介绍了关于Vue数据双向绑定的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • https://github.com/canfoo/self-vue
  • 理解VUE双向数据绑定原理和实现

    千次阅读 多人点赞 2021-02-26 12:04:02
    一、原理: 1.vue 双向数据绑定是通过 数据劫持 结合...2.核心:关于VUE双向数据绑定,其核心是 Object.defineProperty()方法; 3.介绍一下Object.defineProperty()方法 (1)Object.defineProperty(obj, prop, d...
  • 手写Vue源码实现MVVM的响应式原理以及数据双向绑定 帮你理解什么是数据劫持 什么是发布者-订阅者模式 帮你理解Vue内部是如何实现的双向数据绑定 了解Observer Dep Watcher三者之间的关系
  • vue数据双向绑定不上

    2020-07-22 00:30:58
    vue项目中data定义的对象属性无法在页面...如图定义了一个data对象,通过created钩子函数发送了请求拿到了数据一个数据对象,并且想把拿到的数据对象中的某些属性给data中的data,这多简单,直接开干 created() { setT
  • 前段时间笔者学习了一下Vue源码,也看了一些前辈对Vue源码研究的博客,然后用es实现了一个基础的数据双向绑定框架Hue,作为学习成果之一,在此分享给大家。Hue实现了@click,v-model, watch监听属性变化这几个...
  • 觉得不错点个赞哦~ 视频链接: vue极度简化版双向数据绑定源码 转载于:https://juejin.im/post/5ced3c015188252d182056a1
  • 实现vue数据双向绑定

    2020-11-20 09:45:46
    关于vue数据双向绑定也是面试很喜欢问的题目了,这里讲下实现方式,效果图、源码、demo在文章末尾 ​ 首先看下vue的基本结构 <div id="app"> <div>{{a.b.c}}</div> </div> new Vue({ el: ...
  • 发布订阅模式 Angular 的脏查机制 数据劫持 而 Vue2.0 则采用的是数据劫持与发布订阅相结合的方式实现双向绑定数据劫持主要通过 Object.defineProperty 来实现。 Object.defineProperty 这篇文章我们不详细讨论...
  • Vue2 双向绑定原理(数据响应式)

    千次阅读 2020-04-20 12:55:50
    2. Vue2 双向绑定原理(数据响应式) 原理概述 数据劫持 发布与订阅 (一)MVVM 1. 定义: MVVM 是 Model-View-ViewModel(模型-视图-视图模型)的缩写;是一种软件架构设计模式。 其中: Model:是数据模型,既...
  • Vue双向数据绑定主要通过Object.defineProperty来实现,先为所有的属性加上get/set的监控,这样当属性值改变时就会触发对应的set方法,然后再在set方法中通过观察者来更新视图,同时在get方法中进行依赖收集。...
  • 使用vue也好有一段时间了,虽然对其双向绑定原理也有了解个大概,但也没好好探究下其原理实现,所以这次特意花了几晚时间查阅资料和阅读相关源码,自己也实现一个简单版vue双向绑定版本,先上个成果图来吸引各位:...
  • vue数据双向绑定源码分析

    千次阅读 2018-04-13 09:29:15
    VUE中的数据双向绑定是通过数据劫持的方式实现的,核心的便是object.defineProperty(),它内部分为三个部分:observer 可以递归地监听对象上的所有属性,当属性改变时触发相应的watcher。watcher 观察者,当监听的...
  • 1.看了vue 数据双向绑定的源码决定 根据自己的理解 实现一个简单版的 vue双向绑定 首先根据用法 new Vue({…}) 可以知道 vue 构造函数接收一个 对象参数 class Vue { constructor(options){ } } 其次 ...
  • 如果对vue2.xx了解或看过源码的人都知道,vue2.xx中使用 Object.defineProperty()方法对该对象通过 递归+遍历的方式来实现对数据的监控的,具体了解 Object.defineProperty可以看我上一篇文章...
  • 在 MVVM 中,UI 是通过数据驱动的,数据一旦改变就会相应的刷新对应的 UI,UI 如果改变,也会改变对应的数据。 这种方式就可以在业务处理中只关心数据的流转,而 无需直接和页面打交道。ViewModel 只关心数据和业务...
  • vue是一个mvvm框架,双向绑定vue的一个核心功能,所谓双向绑定就是当试图发生改变的时候传递给VM(ViewModel ),让数据得到更新,当数据发生改变的时候传给VM(ViewModel ),使得视图发生变化!概念都知道,但是vue...
  • Vue数据双向绑定的原理

    千次阅读 2018-03-27 17:05:31
    vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的。 双向绑定就是视图上的变化能够反映到数据上,数据上的变化也能反映到视图上。如下图所示: 关键点在于data如何...
  • 此面试题浅层次的解释在:前端面试题:vue双向数据绑定原理,v-model的源码 深层次,其实就是问你vue数据绑定的原理: 1、使用Object.defineProperty进行数据劫持,把data对象,computed等里的所有属性进行数据...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,633
精华内容 2,653
关键字:

vue数据双向绑定源码

vue 订阅