Vue双向绑定原理及实现方法

yizhihongxing

Vue双向绑定原理及实现方法

1. 什么是Vue双向绑定

双向绑定是Vue框架重要的特点之一,意味着当数据发生改变时,视图会随之发生变化,同时视图的修改也会同步到数据中。这种机制使得开发者只需要关注逻辑的实现而不用担心数据如何与视图同步,便于提高开发效率和减少出错概率。

2. 双向绑定原理

Vue中的双向绑定原理主要是通过以下几个步骤实现的:

  1. 数据劫持

首先,在Vue框架被初始化时,Vue会对传入的data数据进行遍历,将所有属性(包括嵌套属性)使用Object.defineProperty()方法进行劫持,以便在属性被读取或者被修改时能够监听到。

function defineReactive(data, key, val) {
  Object.defineProperty(data, key, {
    enumerable: true, // 是否可枚举
    configurable: true, // 是否可删除
    get: function() {
      //...
    },
    set: function(newVal) {
      //...
    }
  })
}

以上代码为数据劫持的具体实现。

  1. 数据的观察者Watcher

接下来,对于每个被劫持的属性,都需要为其创建一个观察者Watcher。Watcher主要负责监听该属性的变化,如果变化则通知Dep(下面介绍),进而触发相应的回调。

function defineReactive(data, key, val) {
    let dep = new Dep() // 一个属性对应一个dep对象
    Object.defineProperty(data, key, {
      enumerable: true,
      configurable: true,
      get: function() {
        if (Dep.target) {
          dep.depend() // watcher向dep对象添加自己
        }
        //...
      },
      set: function(newVal) {
          dep.notify() // dep对象通知所有依赖于它的watcher更新状态
          //...
      }
    })
}

以上代码为定义观察者Watcher的具体实现。

  1. 观察者的订阅者Dep

观察者的订阅者Dep主要负责收集各个观察者Watcher,以便于在数据变化的时候,通知所有依赖于该数据的观察者Watcher进行更新。

class Dep {
  constructor() {
    this.subs = []
  }
  addSub(sub) {
    this.subs.push(sub)
  }
  removeSub(sub) {
    remove(this.subs, sub)
  }
  depend() {
    if (Dep.target) {
      Dep.target.addDep(this)
    }
  }
  notify() {
    const subs = this.subs.slice() // 浅复制,保护this.subs数组
    for (let i = 0, l = subs.length; i < l; i++) {
      subs[i].update()
    }
  }
}
Dep.target = null // 静态属性,watcher的全局存储

以上代码为观察者的订阅者Dep的具体实现。

  1. 解析模板,建立Watcher

在Vue中,数据与视图之间的绑定通过Vue实例的$watch方法实现。
当Vue实例被创建时,会对所有的模板进行解析,建立一个Watcher实例,并且将Watcher实例添加到属性的依赖队列中。

class Watcher {
  constructor() {
    this.deps = []
  }
  addDep(dep) { // 向dep对象注册watcher
    this.deps.push(dep)
    dep.addSub(this)
  }
  update() { // 数据改变,视图刷新
    //...
  }
}

3. 双向绑定实现方法

3.1 Vue 1.x版本双向绑定实现方法:

Vue 1.x版本的双向绑定主要依靠ng-model指令实现,相关代码如下:

<input type="text" v-model="message">

Vue 1.x版本在接收到上述代码的时候,会自动生成以下的代码:

<input
  type="text"
  value="{{message}}"
  oninput="__set_data(message, $event.target.value)"
>

其中,__set_data方法是定义在Vue上的一个私有方法,其实现原理如下:

function makeSetter(exp) {
    return new Function('‘value‘', '‘return this.’ + exp + '=value‘')
}
Vue.prototype.__set_data = function(exp, val) {
  var setter = makeSetter(exp)
  return setter.call(this, val)
}

以上代码为Vue 1.x版本的双向绑定实现方法。

3.2 Vue 2.x版本双向绑定实现方法:

Vue 2.x版本的双向绑定主要借助于Object.defineProperty()方法和响应式设计模式实现。相关代码如下:

<input type="text" v-model="message">

对应的Vue实例代码:

var vm = new Vue({
  el: '#app',
  data: {
    message: ''
  }
})

当输入框中的文本发生变化时,Vue实例会将新值赋值给message变量,然后通过$set方法通知视图进行改变。

Object.defineProperty(vm, key, {
  get: function() {
    //...
  },
  set: function(newVal) {
    if (newVal === val) {
      return;
    }
    val = newVal;
    dep.notify(); // 数据变化通知所有依赖的观察者进行更新
  }
});

以上代码为Vue 2.x版本的双向绑定实现方法。

4. 示例说明

4.1 Vue 2.x版本示例

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

对应的Vue实例代码:

var vm = new Vue({
  el: '#app',
  data: {
    message: ''
  }
})

在上面的示例中,当输入框中的文本发生变化时,Vue实例会将新值赋值给message变量,然后触发视图中的相应指令进行更新。

4.2 Vue 1.x版本示例

<div id="app">
  <input type="text" ng-model="message">
  <p>{{message}}</p>
</div>

对应的Vue实例代码:

var vm = new Vue({
  el: '#app',
  data: {
    message: ''
  }
})

在上面的示例中,当输入框中的文本发生变化时,Vue会自动生成相应的指令,刷新视图。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Vue双向绑定原理及实现方法 - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • Vue中的事件处理详情

    接下来我将为你讲解Vue中的事件处理详情的完整攻略。 一、Vue中的事件处理 在Vue中,事件处理是一个非常重要的概念,这里我们主要讲解如何使用Vue来绑定事件和监听事件。 1. 绑定事件 在Vue中,我们可以使用v-on:或@来绑定事件,其方式如下所示: <!–以下代码为html模板–> <button v-on:click=&quo…

    Vue 2023年5月27日
    00
  • Vue数组更新及过滤排序功能

    Vue数组更新及过滤排序功能 在Vue应用中,数组更新及过滤排序功能是非常常见和重要的,本文将详细讲解Vue中如何实现数组更新以及如何使用过滤和排序功能。 数组更新 Vue异步更新机制 在Vue中,当我们更新数组时,Vue通常会异步更新视图。这是因为在同一事件循环中,多个数据变化可能会导致重复的计算和DOM操作,这样会影响应用的性能。因此,Vue将所有异步数…

    Vue 2023年5月28日
    00
  • Vue中data传递函数、props接收函数及slot传参的使用及说明

    下面是“Vue中data传递函数、props接收函数及slot传参的使用及说明”的完整攻略。 Vue中data传递函数 在 Vue 中,我们可以通过 data 对象来传递数据。但是有时候我们希望传递的是一个函数,这时候该怎么办呢?我们需要将这个函数封装成方法,然后再传递到 data 对象中。示例代码如下: <template> <div&g…

    Vue 2023年5月28日
    00
  • 详解vue-cli脚手架中webpack配置方法

    以下是详解vue-cli脚手架中webpack配置方法的完整攻略。 1. 什么是Vue-cli脚手架和Webpack 1.1 Vue-cli脚手架 Vue-cli是Vue.js官方提供的一个包含脚手架工具和预设的完整系统。它可以帮助我们快速搭建Vue.js开发环境、开发模板及Webpack打包工具。 1.2 Webpack Webpack是一款模块化的打包工…

    Vue 2023年5月28日
    00
  • Vue实现封装一个切片上传组件

    接下来我会详细讲解“Vue实现封装一个切片上传组件”的完整攻略。这个组件可以将一个较大的文件分成多个切片进行上传,可以提高上传速度和稳定性。 1. 开始编写组件 首先,我们需要创建一个名为“SliceUpload”的Vue组件,可以使用如下代码创建: <template> <div class="slice-upload&quot…

    Vue 2023年5月28日
    00
  • 理解Proxy及使用Proxy实现vue数据双向绑定操作

    理解 Proxy 在 JavaScript 中,对象是一种引用类型,对象的属性只是指向变量的一个指针。因为这个特性,我们可以获得代理模式的能力:在对象创建之后,可以创建一个代理来控制对象的访问或操作。 Proxy 对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。这样,我们可以在读取或修改对象属性时插入其他逻辑,例如数据绑定。 在使用 …

    Vue 2023年5月28日
    00
  • 利用vite创建vue3项目的全过程及一个小BUG详解

    下面我将详细讲解如何利用 Vite 创建 Vue 3 项目的全过程,并对遇到的一个小 BUG 进行详解。 1. 安装 Vite 首先,我们需要全局安装 Vite: npm install -g vite 2. 创建项目 创建一个基于 Vue 3 的项目可以使用 Vue CLI 4.x 或者使用 Vite + Vue 3。这里我们使用 Vite + Vue 3…

    Vue 2023年5月27日
    00
  • 快速掌握Vue3.0中如何上手Vuex状态管理

    快速掌握Vue3.0中如何上手Vuex状态管理 在Vue 3.0 中使用Vuex状态管理有以下步骤: 第一步:安装 Vuex 使用npm或yarn进行安装: // npm npm install vuex@next // yarn yarn add vuex@next 第二步:创建store 创建一个store.js文件来管理你的状态管理: import {…

    Vue 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部