理解vue的响应式原理、双向绑定原理、虚拟dom

三者关系

Vue的响应式原理、双向绑定、虚拟DOM之间是一种协同工作的关系,它们共同构成了Vue框架的核心特性,用于实现数据驱动的视图更新。

  • 响应式原理为基础: 响应式原理是Vue实现数据和视图关联的基础,确保数据的变化能够被观察到。

  • 双向绑定建立在响应式基础上: 双向绑定通过v-model等指令建立在响应式系统的基础上,使得视图和数据之间能够实现双向同步。

  • 虚拟DOM优化性能: 虚拟DOM作为性能优化的手段,通过比对新旧虚拟DOM,最小化对实际DOM的操作,提高了页面渲染的效率。

这三者相互协同工作,使得Vue能够高效地实现数据驱动的视图更新,同时确保了开发者能够以简洁的方式处理复杂的用户界面逻辑。

详解

1、响应式原理

数据驱动视图。数据变化,页面也跟着变化。

Vue2.x是借助Object.defineProperty()实现的,而Vue3.x是借助Proxy实现的

1、vue2.xObject.defineProperty()

Object.defineProperty(obj, key, {
    enumerable: true,//控制属性是否会出现在对象的属性枚举中
    configurable: true,//控制属性的可配置性,即是否可以使用 Object.defineProperty 修改属性的特性,是否可以删除属性。
    //拦截get,当我们访问data.key时会被这个方法拦截到
    get: function getter () {
        //我们在这里收集依赖
        return obj[key];
    },
    //拦截set,当我们为data.key赋值时会被这个方法拦截到
    set: function setter (newVal) {
        //当数据变更时,通知依赖项变更UI
    } 
})

Object.defineProperty 允许定义一个对象属性,其中包含 getter setter 函数。getter 在每次访问属性时触发,setter 在每次修改属性时触发。

当我们通过obj.aobj['a'] 获取属性时,getter 函数会执行,且收集到一个集合中。这样,当属性的值发生变化时,就知道哪些地方依赖于这个属性,需要进行相应的更新。

当我们给属性赋值时,setter 函数会触发。在这个函数中,我们通知之前收集的依赖进行更新,确保数据的变更能够驱动视图的变更。这样就实现了 数据驱动视图
2、vue3.x使用的是Proxy ,与vue2.x思想一致,
Proxy 的优势在于它提供了更强大和灵活的拦截能力,相比于 Object.defineProperty,它可以直接代理整个对象,而不需要像前者一样对每个属性进行处理。这使得 Vue 3.x 的响应式系统更加高效、灵活

// 创建一个响应式对象
function reactive(obj) {
  return new Proxy(obj, {
    get(target, key, receiver) {
      console.log(`Getter: ${key}`);
      const value = Reflect.get(target, key, receiver);
      // 如果属性值是对象,递归地返回代理对象
      return typeof value === 'object' ? reactive(value) : value;
    },
    set(target, key, value, receiver) {
      console.log(`Setter: ${key}`);
      // 使用 Reflect.set 设置属性值
      const result = Reflect.set(target, key, value, receiver);
      // 触发更新
      // 这里可以加上通知更新的逻辑,例如触发重新渲染
      return result;
    }
  });
}

2、双向绑定

Vue的双向绑定是指数据模型Model和视图View之间的同步关系是双向的,当一个改变时,另一个也会相应地发生变化。在Vue中,最常见的双向绑定是通过v-model指令实现的,通常用于表单元素(如<input><textarea><select>)。

<template>
   <input v-model='myValue'/>
</template>

相当于

<template>
   <input @input='onInput' :value='myValue' />
   <span>{{myValue}}</span>
</template>
<script>
  export default{
    data(){
      return {
        myValue:'',
      }
    },
    methods:{
      onInput(e){
         this.myValue=e.target.value;
         console.log(this.myValue)
      }
    }
  }
</script>

当用户在表单元素中输入内容时,input事件触发,将输入的新值反映到数据模型;反之,当数据模型的值改变时,相应的value属性的变化会导致视图的更新(数据驱动视图)。
这就实现了双向绑定

3、虚拟dom

Vue使用虚拟DOM(Virtual DOM)作为一种性能优化手段,以提高页面渲染的效率。虚拟DOM是一个内存中的表示真实DOM结构的JavaScript对象树,通过对比新旧虚拟DOM的差异,最终只对发生变化的部分进行实际的DOM操作,从而减少了对真实DOM的直接操作,提高了性能。

以下是Vue虚拟DOM的基本工作原理:

  1. 初始渲染: 当页面首次加载或数据发生变化时,Vue会创建一个虚拟DOM,该虚拟DOM对应着整个组件的DOM结构。

  2. 更新触发: 当数据发生变化时,Vue会生成一个新的虚拟DOM树。

  3. 虚拟DOM Diff(差异)算法: Vue会将新旧虚拟DOM进行比较,找到两者之间的差异。这个比较过程被称为虚拟DOM Diff算法。

    • 快速比较: 通过对比两个虚拟DOM树的差异,Vue能够快速定位到发生变化的节点,而无需对整个DOM树进行比较。
  4. 差异更新: Vue会根据差异,只更新发生变化的部分到真实DOM中,而不是重新渲染整个DOM树。

    • 最小化DOM操作: 这个过程可以大大减少实际的DOM操作次数,从而提高性能。因为对真实DOM的操作是相对昂贵的,通过最小化这些操作,可以更有效地更新用户界面。
  5. 渲染到真实DOM: 最后,将更新后的虚拟DOM渲染到真实DOM中,使视图与数据保持同步。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Vue.js 的双向数据绑定的原理是通过 Object.defineProperty 来实现的。 当 Vue 实例创建时,它会遍历 data 对象中的每一个属性,使用 Object.defineProperty 将这些属性转换为 getter/setter。 在 Vue 实例中,每个组件都是一个单独的作用域,当绑定的数据发生变化时,Vue 实例通过 getter/setter 检测到变化,并触发相应的视图更新。 通过这种方式,Vue 实现了数据与视图之间的双向绑定,可以让开发者可以只关注数据的更新,而不需要关注视图的更新。 ### 回答2: Vue.js 是一种基于 MVVM 模式的前端框架,其提供了双向数据绑定的能力。双向数据绑定意味着当数据发生改变时,视图会自动更新;反之,当视图发生改变时,数据也会相应地更新。 Vue 的双向数据绑定原理主要依靠了它的响应式系统。当我们在 Vue 的实例中声明了一个数据属性时,Vue 会使用 Object.defineProperty() 方法将该数据属性转换为 getter 和 setter。这样,当我们通过 Vue 实例访问该数据属性时,实际上是调用了 getter 方法,从而获得该数据属性的值;当我们修改该数据属性的值时,实际上是调用了 setter 方法,从而更新数据属性的值。 Vue 在实例化时会对模板进行解析,将模板中的指令、表达式等转换为对应的数据绑定。例如,将 "{{ message }}" 转换为数据属性 "message" 的使用。 当数据发生改变时,Vue响应式系统会通过依赖追踪机制,收集与该数据属性相关的依赖(例如视图中使用了该数据属性的地方)。当数据属性的 setter 方法被调用时,Vue 会通知相关的依赖更新视图,从而实现了数据的双向绑定。 另外,在视图中,Vue 通过使用指令和表达式等语法糖来实现数据的绑定。例如,v-bind 指令可以将一个属性和一个表达式绑定,当表达式的值发生变化时,属性的值也会相应更新。 综上所述,Vue 的双向数据绑定原理主要依赖于它的响应式系统,通过对数据属性的 get 和 set 方法进行拦截和监听,实现了数据的双向绑定。同时,Vue 还提供了丰富的语法糖,便于开发者进行数据绑定的操作。 ### 回答3: Vue.js的双向数据绑定是通过Vue实例中的数据监听器和指令来实现的。 首先,Vue会将页面中的模板解析成AST(抽象语法树)并创建渲染函数。当数据发生变化时,Vue会重新执行渲染函数并生成新的虚拟DOM树。 在数据监听器部分,Vue会使用Object.defineProperty来重写数据对象的get和set方法。这样一来,当我们读取数据时,Vue会将该属性添加到依赖收集器中。而当我们修改数据时,Vue则会通知订阅者,执行相应的更新操作。 指令的作用是将视图和数据进行绑定。Vue中的v-model指令可以实现双向数据绑定,它会根据不同的输入元素类型创建不同的事件监听器,并在值改变时更新数据。 具体地说,当我们在输入框中输入内容时,触发的input或change事件会被v-model指令监听到,并将输入的值赋给数据。而当数据发生变化时,数据监听器会通知订阅者,订阅者再通过渲染函数更新视图,以保持数据和视图的同步。 另外,Vue还通过虚拟DOM和Diff算法来优化性能。当数据发生变化时,Vue会比较新旧虚拟DOM树的差异,然后只更新需要变化的部分,避免重新渲染整个视图。 总的来说,Vue的双向数据绑定原理是通过数据监听器和指令来实现的。数据监听器通过重写数据对象的get和set方法来收集依赖和触发更新,而指令则负责将视图和数据进行绑定和更新。通过这种机制,数据和视图可以实现实时同步,极大地提高了开发效率和用户体验。

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值