likes
comments
collection
share

一篇文章搞懂Vue2框架双向绑定的实现原理

作者站长头像
站长
· 阅读数 33

Vue2框架双向绑定的实现原理

双向绑定的基本概念

在Vue2框架中,双向绑定是指视图层和数据层之间的自动同步。当视图层中的数据发生变化时,数据层中的数据也会随之变化;反之,当数据层中的数据发生变化时,视图层中的数据也会随之变化。

双向绑定的实现原理

Vue2框架中的双向绑定是通过数据劫持和发布-订阅模式来实现的。

数据劫持

Vue2框架中的数据劫持是通过Object.defineProperty()方法来实现的。该方法可以监听一个对象的属性,并在属性值发生变化时触发相应的回调函数。具体来说,Vue2框架会将数据层中的每个属性都转化为getter和setter方法,当视图层读取或修改这些属性时,就会触发相应的getter或setter方法,从而实现数据的监听和同步。

例如,假设有一个Vue实例,其中有一个data属性,如下所示:

var vm = new Vue({
  data: {
    message: 'Hello Vue!'
  }
})

在这个例子中,message属性被转化为getter和setter方法,如下所示:

var data = {
  message: 'Hello Vue!'
}

Object.defineProperty(data, 'message', {
  get: function () {
    console.log('getter被调用了')
    return this._message
  },
  set: function (newValue) {
    console.log('setter被调用了')
    this._message = newValue
  }
})

data.message // 输出:getter被调用了 Hello Vue!
data.message = 'Hello World!' // 输出:setter被调用了

从上述代码可以看出,当我们读取或修改message属性时,会分别触发相应的getter和setter方法。

发布-订阅模式

Vue2框架中的发布-订阅模式是通过一个事件中心来实现的。该事件中心负责管理所有的事件和相应的回调函数,当某个事件被触发时,事件中心会自动调用相应的回调函数。

在Vue2框架中,事件中心被封装在Dep类中。每个数据属性都会对应一个Dep实例,当该属性被读取或修改时,就会触发相应的getter或setter方法,并通知Dep实例,从而实现数据的自动同步。

例如,假设有一个Vue实例,其中有一个data属性,如下所示:

var vm = new Vue({
  data: {
    message: 'Hello Vue!'
  }
})

在这个例子中,message属性对应的Dep实例如下所示:

function Dep() {
  this.subs = []
}

Dep.prototype.addSub = function (sub) {
  this.subs.push(sub)
}

Dep.prototype.notify = function () {
  this.subs.forEach(function (sub) {
    sub.update()
  })
}

var data = {
  message: 'Hello Vue!'
}

Object.defineProperty(data, 'message', {
  get: function () {
    console.log('getter被调用了')
    if (Dep.target) {
      Dep.target.addDep(this.dep)
    }
    return this._message
  },
  set: function (newValue) {
    console.log('setter被调用了')
    this._message = newValue
    this.dep.notify()
  }
})

data.dep = new Dep()

var watcher = {
  update: function () {
    console.log('视图层更新了')
  }
}

Dep.target = watcher
data.message // 输出:getter被调用了
Dep.target = null

data.message = 'Hello World!' // 输出:setter被调用了 视图层更新了

从上述代码可以看出,当我们读取或修改message属性时,会触发相应的getter或setter方法,并通知对应的Dep实例。该Dep实例会自动调用所有订阅了该属性的Watcher实例的update()方法,从而实现视图层和数据层之间的自动同步。

举例说明

假设有一个Vue实例,其中有一个message属性和一个input元素,如下所示:

<div id="app">
  <input type="text" v-model="message">
</div>

<script>
  var vm = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue!'
    }
  })
</script>

在这个例子中,当我们在input元素中输入文字时,该文字会自动同步到message属性中;反之,当我们修改message属性时,input元素中的文字也会自动更新。

这种自动同步的机制是通过Vue2框架的双向绑定实现的。具体来说,当我们在input元素中输入文字时,会触发相应的input事件,从而自动修改message属性;反之,当我们修改message属性时,会触发相应的setter方法,从而自动更新input元素中的文字。

总结

Vue2框架的双向绑定是通过数据劫持和发布-订阅模式来实现的。数据劫持可以监听数据层中的属性,从而实现数据的自动同步;发布-订阅模式可以管理所有的事件和相应的回调函数,从而实现视图层和数据层之间的自动同步。这种自动同步的机制使得开发者可以更加方便地管理数据和视图。

转载自:https://juejin.cn/post/7240004799721209917
评论
请登录