vue 双向数据绑定的原理?

本文详细解释了Vue如何通过数据劫持和发布-订阅模式实现双向数据绑定,涉及Object.defineProperty(),Dep和Watcher等关键概念。当输入值变化时,视图能实时更新。
摘要由CSDN通过智能技术生成

在Vue中,实现双向数据绑定的原理是通过数据劫持和发布-订阅模式来实现的。

首先,Vue会对data中的所有属性进行劫持,即通过Object.defineProperty()方法来劫持属性的getter和setter方法。当获取属性值时,会触发getter方法,而当修改属性值时,会触发setter方法。

然后,Vue会为每个属性创建一个依赖收集器(Dep),依赖收集器用来存储当前属性的所有订阅者(Watcher)。

当模板中使用了属性的时候,会创建一个Watcher,Watcher会将自身添加到属性的依赖收集器中,并将依赖收集器添加到自身的订阅者列表中。

当属性的值发生改变时,会触发属性的setter方法,setter方法会通知依赖收集器中的所有订阅者,然后订阅者会更新视图。

以下是一个简单的示例代码:

HTML:

<div id="app">
  <input v-model="message" />
  <p>{{ message }}</p>
</div>

JavaScript:

// 创建Vue实例
let vm = new Vue({
  el: '#app',
  data: {
    message: ''
  }
})

// 数据劫持及订阅-发布模式的实现
class Dep {
  constructor() {
    this.subscribers = []
  }
  
  addSubscriber(subscriber) {
    this.subscribers.push(subscriber)
  }
  
  notify() {
    this.subscribers.forEach(subscriber => subscriber.update())
  }
}

class Watcher {
  constructor(vm, key, updateFn) {
    this.vm = vm
    this.key = key
    this.updateFn = updateFn
    
    Dep.target = this
    this.vm[this.key]
    Dep.target = null
  }
  
  update() {
    this.updateFn.call(this.vm, this.vm[this.key])
  }
}

function defineReactive(obj, key, val) {
  let dep = new Dep()
  Object.defineProperty(obj, key, {
    get() {
      dep.addSubscriber(Dep.target)
      return val
    },
    set(newVal) {
      if (newVal !== val) {
        val = newVal
        dep.notify()
      }
    }
  })
}

function observe(obj) {
  if (!obj || typeof obj !== 'object') {
    return
  }
  
  Object.keys(obj).forEach(key => {
    defineReactive(obj, key, obj[key])
  })
}

observe(vm)

// 单向绑定的实现
let input = document.querySelector('input')
let p = document.querySelector('p')

// 更新model
input.addEventListener('input', function() {
  vm.message = this.value
})

// 更新视图
new Watcher(vm, 'message', function(value) {
  p.innerText = value
})

在上述示例中,我们通过Object.defineProperty()方法对data中的message属性进行劫持,并实现了依赖收集器Dep和订阅者Watcher。当input的值发生变化时,会通过setter方法触发依赖收集器的notify()方法,进而更新订阅者的视图。

这样,当input中的值发生变化时,p标签中的内容也会实时更新。这就实现了双向数据绑定。

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值