vue2.x 对象劫持的原理实现

yizhihongxing

Vue.js 通过 Object.defineProperty() 函数,对对象的属性进行劫持,实现了数据双向绑定的功能。

具体的实现过程如下:

  1. Vue.js 给每个组件对象(包含 data 属性)都创建了一个 Observer 对象,并将 data 属性的值递归地遍历,使用 Object.defineProperty() 函数将 data 属性的每个属性都转换成 getter/setter。

  2. 在 getter 中,Vue.js 将该属性的 Dep 实例加入到 Watcher 实例的依赖列表中。Dep 实例是一个容器,存储着 Watcher 实例的引用。

  3. 在 setter 中,如果该属性的值发生了变化,则 Vue.js 遍历该属性的 Dep 实例的依赖列表(即 Watcher 实例列表),然后逐个调用依赖项的 update() 方法,更新页面显示的内容。

下面是一个示例说明:

// 定义一个对象
const obj = { a: 1 }

// 使用 Object.defineProperty() 函数实现劫持
Object.defineProperty(obj, 'a', {
  get() {
    console.log('getter')
    return a
  },
  set(val) {
    console.log('setter')
    a = val
  }
})

// 访问属性 a
console.log(obj.a) // 输出 "getter" 和 "1"

// 修改属性 a
obj.a = 2 // 输出 "setter"
console.log(obj.a) // 输出 "getter" 和 "2"

在上面的示例中,当我们读取 obj.a 属性时,会打印出 "getter" 和属性的值 "1"。当我们修改 obj.a 属性时,会打印出 "setter"。这种设置 getter/setter 的方式,就是 Vue.js 实现数据双向绑定的关键所在。

下面是另一个示例,模拟 Vue.js 中的 Watcher 和 Dep 功能:

// 定义一个 Watcher 类
class Watcher {
  constructor() {
    Dep.target = this
  }
  update() {
    console.log('update')
  }
}

// 定义一个 Dep 类
class Dep {
  constructor() {
    this.subs = []
  }
  addSub(sub) {
    this.subs.push(sub)
  }
  notify() {
    this.subs.forEach(sub => sub.update())
  }
}

// 使用 Watcher 和 Dep 类实现属性劫持
const obj2 = {}
let val2
Object.defineProperty(obj2, 'a', {
  get() {
    console.log('getter')
    Dep.target && Dep.target.addDep(this)
    return val2
  },
  set(val) {
    console.log('setter')
    val2 = val
    this.dep.notify()
  }
})

// 创建 Watcher 实例
const watcher = new Watcher()

// 访问属性 a
obj2.a // 输出 "getter"

// 修改属性 a
obj2.a = 2 // 输出 "setter" 和 "update"

在上面的示例中,我们分别定义了 Watcher 和 Dep 两个类,用来模拟 Vue.js 中的 Watcher 和 Dep 功能。在 getter 中,我们调用了 addDep() 方法,用来将 Watcher 实例添加到 Dep 实例的依赖列表中。在 setter 中,我们调用了 dep.notify() 方法,用来通知依赖该属性的 Watcher 实例执行 update() 方法。最后,创建了一个 Watcher 实例,来监听属性 a 的变化。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue2.x 对象劫持的原理实现 - Python技术站

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

相关文章

  • js数组的 entries() 获取迭代方法

    当使用JavaScript中的数组时,我们通常会遍历数组中的元素,以便执行某些操作。而ES6中的数组新增了entries()方法,它返回一个新的迭代器对象,该对象按照索引的方式遍历数组的键值对。它可以帮助我们更方便的实现循环遍历的操作。 1. entries()方法的使用 在JavaScript中使用数组的entries()方法,我们首先需要获取一个数组对象…

    Vue 2023年5月29日
    00
  • Vue六大基本类型中的原始值响应式

    Vue六大基本类型中的原始值响应式是指 Vue 对于 JavaScript 基本数据类型的响应式实现,包括 Number、String、Boolean 和 Symbol 四个类型的数据。 Vue 对于这些数据类型的响应式实现是通过 Object.defineProperty() 方法来实现的。当 Vue 检测到数据发生变化时,会调用数据的 setter 方法…

    Vue 2023年5月28日
    00
  • 用electron打包vue项目中的报错问题及解决

    下面是关于用electron打包vue项目中的报错问题及解决的完整攻略。 标题 用electron打包vue项目中的报错问题及解决 背景 Vue是一种流行的JavaScript前端框架,可以快速搭建现代Web应用程序。但是,当我们要将Vue项目打包成桌面应用程序时,我们通常会遇到各种报错问题。这些问题可能会让我们在打包应用程序时感到困惑和疑惑。在本文中,我们…

    Vue 2023年5月29日
    00
  • vue用Object.defineProperty手写一个简单的双向绑定的示例

    下面是Vue用Object.defineProperty手写一个简单的双向绑定的攻略。 双向绑定是指当数据改变时,视图也会随之更新,而当视图改变时,数据也会随之更新。Vue是一款双向绑定的框架,它通过观察者模式实现了数据与视图的同步更新。其核心原理就是利用Object.defineProperty()方法对数据进行拦截和劫持,实现数据变更时视图的更新操作。下…

    Vue 2023年5月28日
    00
  • vue.js语法及常用指令

    下面是关于“vue.js语法及常用指令”的完整攻略。 一、Vue.js语法 Vue.js 是一款流行的 JavaScript 框架,它的语法和模板采用了基于 HTML 的模板语法,简化了前端开发中数据绑定和 DOM 操作的复杂度。下面是 Vue.js 的一些基本语法: 1. 基本模板 Vue.js 的基本模板由普通的 HTML 标签和 Vue.js 的特殊属…

    Vue 2023年5月27日
    00
  • 用vue设计一个数据采集器

    用vue设计一个数据采集器的完整攻略: 1. 确定需求: 首先我们要明确数据采集器的需求,主要包括要采集哪些数据、如何展示这些数据、如何进行数据的上传和保存等问题。 2. 设计界面: 接下来,我们需要设计数据采集器的界面,这里建议采用UI框架,如elementUI等,大大加快开发速度。 3. 构建组件: 按照需求和设计的界面,我们可以将整个数据采集器拆分成多…

    Vue 2023年5月28日
    00
  • vue里使用create,mounted调用方法的正确姿势说明

    接下来我来详细讲解“Vue中使用created和mounted调用方法的正确方式”。 1. created 和 mounted Vue 组件的生命周期函数可以分为 beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed。今天我们主要来讲解其中的…

    Vue 2023年5月28日
    00
  • Vue通过字符串关键字符实现动态渲染input输入框

    当我们需要动态生成一个输入框时,在Vue中可以通过字符串关键字符来实现,以下是具体步骤: 在Vue组件中定义一个data属性,用于存储动态生成的输入框的值 data() { return { inputValue: ” } }, 在模板中使用v-model绑定data属性,将动态生成的输入框与data属性进行双向绑定 <template> &l…

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