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

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日

相关文章

  • 公共Hooks封装文件下载useDownloadFile实例详解

    我会为你详细讲解“公共Hooks封装文件下载useDownloadFile实例详解”的完整攻略。 什么是公共Hooks 公共Hooks是指在React项目中,可以被多个组件共享的可重用代码片段。它们通常被封装在统一的模块中,以便于其他组件引用和使用。 useDownloadFile Hook useDownloadFile Hook是一个公共Hooks封装文…

    Vue 2023年5月28日
    00
  • 使用vue3搭建后台系统的详细步骤

    使用Vue3搭建后台系统的详细步骤: 1. 安装Vue CLI 使用Vue CLI可以帮助我们快速地搭建Vue项目环境,可以使用以下命令安装: npm install -g @vue/cli 2. 创建项目 可以使用以下命令创建一个基于Vue3的项目: vue create my-project 3. 安装其他依赖 除了Vue CLI生成的默认依赖外,我们还…

    Vue 2023年5月27日
    00
  • 详解Vue如何监测数组的变化

    详解Vue如何监测数组的变化。Vue对数组的变化是有所监测的,包括以下操作:push、pop、shift、unshift、splice、sort、reverse。下面我们对这些操作进行分析: push和pop Vue对于数组的push、pop操作,可以通过观察数组的length属性来监测数组的变化。当进行push或pop操作时,Vue会检测到数组的lengt…

    Vue 2023年5月28日
    00
  • vue组件 非单文件组件的使用步骤

    使用vue组件的方法有两种:单文件组件和非单文件组件。 非单文件组件的使用步骤如下: 定义组件 定义非单文件组件有两种方法,一种是使用Vue.component()函数,另一种是使用全局的组件注册方法。 使用Vue.component()函数: Vue.component(‘my-component’, { template: ‘<div>{{ …

    Vue 2023年5月28日
    00
  • Vue项目中如何使用Axios封装http请求详解

    使用Axios进行http请求可以帮助我们快速的开发Vue项目,Axios支持浏览器、node.js和可以异步的进程通信。在Vue项目中,我们可以封装Axios进行http请求,以便于让我们的代码更加集中和易于维护。 下面就是Vue项目中如何使用Axios封装http请求的详细攻略: 1. 安装Axios 首先,在Vue项目中使用Axios,需要进行安装。运…

    Vue 2023年5月28日
    00
  • 详解Vue组件实现tips的总结

    我来为您详细讲解“详解Vue组件实现tips的总结”的完整攻略。 一、什么是tips tips是一种浮动提示框,通常用于提示用户需要注意的内容。在Vue组件中实现tips功能,可以提升用户体验,让用户更加方便地获取信息。 二、实现方式 Vue组件实现tips的方式主要有以下几种: 1. 使用原生JS实现 使用原生JS编写tips功能的代码量较大,而且需要考虑…

    Vue 2023年5月27日
    00
  • 详解离线安装npm包的几种方法

    当我们需要使用npm包时,通常我们会使用npm命令在线安装。但是,某些情况下我们可能需要离线安装npm包,比如网络环境不佳或无法联网的情况下。 本文将为大家详细讲解“详解离线安装npm包的几种方法”。 方法一:使用npm install命令 在网络良好的情况下,可以使用npm install命令将需要的npm包从线上下载到本地文件系统,这样就可以在没有网络的…

    Vue 2023年5月28日
    00
  • vue watch监控对象的简单方法示例

    下面是详细讲解 “Vue watch 监控对象的简单方法示例” 的完整攻略。 什么是 Vue Watch? Vue 是一个响应式框架,数据的变化能够自动触发视图的更新。Vue Watch 提供了一种方式来监听 Vue 实例中某个数据的变化,当它的值发生变化时,可以触发特定的操作。 如何在 Vue 中使用 Watch 在 Vue 实例中,可以使用 watch …

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