Vue之Dep和Observer的用法及说明

Vue之Dep和Observer的用法及说明

什么是Dep

Dep(Dependence)是 Vue.js 内部实现响应式的核心。

Dep负责维护和管理所有的Watcher对象,所有被观察者(即响应式数据)的get函数中都会收集自己的依赖(Dep对象)到自己的dep中。

Dep的实现

Dep类的定义如下:

class Dep {
    constructor () {
        this.subs = []
    }

    addSub (sub) {
        this.subs.push(sub)
    }

    removeSub (sub) {
        remove(this.subs, sub)
    }

    depend () {
        if (window.target) {
            window.target.addDep(this)
        }
    }

    notify () {
        // stabilize the subscriber list first
        const subs = this.subs.slice()
        for (let i = 0, l = subs.length; i < l; i++) {
            subs[i].update()
        }
    }
}

Observer 的实现

Observer 将一个对象上的所有属性转化为 getter/setter 的形式,以便“响应式”系统可以侦测到属性的读取和修改事件。当一个响应式数据被访问时(即执行get方法时),Dep会自动把当前的Watcher对象添加到自己的subs数组中,等到数据发生变更时,所有被观察者会被通知更新数据(即执行update方法)。

class Observer {
    constructor (value) {
        this.value = value
        this.dep = new Dep()

        // 重写所有属性的getter/setter
        Object.keys(value).forEach(key => {
            defineReactive(value, key)
        })
    }
}

// 将对象的属性转化为getter/setter的形式
export function defineReactive (obj, key, val) {
    const dep = new Dep()

    const property = Object.getOwnPropertyDescriptor(obj, key)
    if (property && property.configurable === false) {
        return
    }
    const getter = property && property.get
    const setter = property && property.set

    if ((!getter || setter) && arguments.length === 2) {
        val = obj[key]
    }

    Object.defineProperty(obj, key, {
        enumerable: true,
        configurable: true,
        get: function reactiveGetter () {
            const value = getter ? getter.call(obj) : val
            if (window.target) {
                dep.depend()
            }
            return value
        },
        set: function reactiveSetter (newVal) {
            const value = getter ? getter.call(obj) : val
            if (newVal === value) {
                return
            }
            if (setter) {
                setter.call(obj, newVal)
            } else {
                val = newVal
            }
            dep.notify()
        }
    })
}

示例说明

我们在Vue实例中,通常会将data对象中的属性转化为响应式的数据,以便Vue可以检测到数据变化,从而实现视图自动更新。我们使用以下示例来说明Dep和Observer的用法:

// 假设我们有以下初始数据
const data = {
  name: 'John Smith',
  age: 35
}

// 将初始数据转换为Observer对象,实现数据的响应式
const observer = new Observer(data)

// 添加一个Watch实例来监控数据的变化
const watcher = new Watcher(() => {
  console.log('name changed:', data.name)
})

// 修改name属性的值
data.name = "Mary Johnson"

// 这时会触发watcher的update方法,在控制台输出: name changed: Mary Johnson

在这个示例中,我们通过将 data 对象转换为 Observer 对象来实现数据的响应式,然后创建Watcher对象来监控特定的数据变化,最后修改name属性的值时,watcher对象的update方法会被触发,从而在控制台输出新的值。

这样通过Dep和Observer的封装,我们可以很容易地实现 Vue 的响应式数据更新和视图重渲染。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Vue之Dep和Observer的用法及说明 - Python技术站

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

相关文章

  • 一步步教你利用webpack如何搭一个vue脚手架(超详细讲解和注释)

    一步步教你利用Webpack如何搭一个Vue脚手架 本文将指导你如何使用Webpack搭建一个Vue脚手架,我们将一步步地进行详细地讲解,让你可以轻松地实现一个基本的Vue项目。 创建项目目录 首先,我们需要创建一个新的项目目录,并在其中创建一个package.json文件,以便我们可以安装所需的依赖项: mkdir vue-starter cd vue-s…

    Vue 2023年5月28日
    00
  • vue项目首屏加载过慢的一些解决方案

    首屏加载慢是vue项目中常见的问题,以下是一些解决方案。 1. 代码分割 由于Vue的单页面应用,一旦一个组件被请求,整个应用程序将被加载到浏览器中。这就导致了首屏加载速度缓慢的问题。通过代码分割,将应用程序分解成更小的块,可以减少加载时间并改善用户体验。 Vue官方提供了vue/cli脚手架工具,其中webpack已经默认配置好了代码分割。通过动态导入组件…

    Vue 2023年5月29日
    00
  • vuex操作state对象的实例代码

    下面是详细讲解“Vuex操作state对象的实例代码”的攻略。 1. 理解Vuex和state对象的基本概念 Vuex是一个专门为Vue.js设计的状态管理库,主要用于管理Vue.js应用程序中的状态。在使用Vuex的过程中,最核心的概念就是state对象。 state对象是Vuex中的一个重要部分,它类似于Vue.js组件中的data对象,但是它被所有组件…

    Vue 2023年5月28日
    00
  • Vue 搭建Vuex环境详解

    Vue 搭建Vuex环境详解 简介 Vuex是Vue.js的官方状态管理库,它可以更好的管理Vue.js应用中的数据流,包括数据的状态、存储和同步。社区中已经有很多文章介绍Vuex的基础使用,本文将详细讲解如何在Vue.js中搭建Vuex环境,并提供两个示例说明。 搭建Vuex环境 安装Vuex 在Vue.js项目中使用Vuex,需要先安装它。 npm in…

    Vue 2023年5月28日
    00
  • three.js 如何制作魔方

    制作魔方可以使用 three.js 的几何体和材质系统。下面是操作的步骤: 步骤一:创建魔方容器 首先需要使用 THREE.Object3D 类创建一个空容器,作为存放所有魔方块的父节点: const container = new THREE.Object3D(); scene.add(container); 步骤二:创建小立方体 接下来需要创建小立方体,…

    Vue 2023年5月28日
    00
  • vue-element-admin 全局loading加载等待

    Vue-Element-Admin 是一个基于 Vue.js 的前端管理系统框架,该框架支持全局loading加载等待功能,可以有效提升用户体验。下面将介绍如何在 Vue-Element-Admin 中使用全局loading加载等待功能的完整攻略。 添加全局loading组件 首先,在 src/layout/components/AppMain.vue 文件…

    Vue 2023年5月28日
    00
  • vue使用directive限制表单输入整数、小数的方法

    下面是详细讲解“vue使用directive限制表单输入整数、小数的方法”的完整攻略: 一、什么是directive 在Vue中,Directive(指令)是一种特殊的标记,它可以在模板中添加行为。在Vue中,有很多自带的directive,例如v-model、v-if、v-show等。通过使用Directive,开发者可以自定义自己的指令。Vue中,Dir…

    Vue 2023年5月28日
    00
  • javascript实现简易的计算器功能

    下面就是“JavaScript实现简易的计算器功能”的攻略。 步骤 创建HTML页面,包含一个输入框和数字、运算符按钮。 “`html JavaScript计算器 JavaScript计算器 7 8 9 + 4 5 6 – 1 2 3 * 0 . C / = “` 创建JavaScript文件,并编写buttonClick函数,用于处理按钮点击事件。 j…

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