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日

相关文章

  • vue实现虚拟列表组件解决长列表性能问题

    Vue是一个流行的JavaScript框架,其易于使用和高度灵活的特性使得在前端开发中广泛应用。但是在处理长列表时,用Vue来渲染数据容易导致页面性能下降,尤其是在移动浏览器中。为了提高Vue性能,在Vue官方文档中提供了一种解决长列表性能问题的机制,那就是使用算法实现虚拟列表,从而避免渲染大量无意义数据。本文将详细介绍如何使用Vue实现虚拟列表组件,包括以…

    Vue 2023年5月27日
    00
  • 浅谈vuex为什么不建议在action中修改state

    下面为您详细讲解“浅谈vuex为什么不建议在action中修改state”的攻略。 什么是Vuex Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 基于 Vue.js 组件树的基础之上提供了一个全局的状态管理机制。 什么是Action Act…

    Vue 2023年5月28日
    00
  • vue实现列表倒计时

    想要实现列表倒计时,可以使用Vue框架中的定时器方法和计算属性来实现。具体实现的过程如下: 步骤一:在App.vue文件中创建数据 <template> <div> <ul> <li v-for="(item, index) in items" :key="index">…

    Vue 2023年5月29日
    00
  • vue实现时间倒计时功能

    以下是“vue实现时间倒计时功能”的完整攻略,希望能对您有所帮助。 基本思路 Vue 实现时间倒计时功能的基本思路是:获取倒计时的起始时间和结束时间,然后通过 setInterval 函数计算时间差并更新视图上的倒计时剩余时间。 具体步骤 1.在Vue组件中定义起始时间和结束时间。 data() { return { startTime: new Date(…

    Vue 2023年5月28日
    00
  • Vue异步更新DOM及$nextTick执行机制解读

    Vue异步更新DOM及$nextTick执行机制解读 在 Vue 中,DOM 更新并不是同步执行的,除非使用 this.$nextTick 方法,它可以保证在本次 DOM 更新后执行回调函数,下面我就来详细解读这个机制。 异步更新DOM Vue 在进行 DOM 更新时,通常借助浏览器的异步更新机制,将多个数据变更合并为一次更新,以提高更新效率。这个机制体现在…

    Vue 2023年5月29日
    00
  • axios post提交formdata的实例

    下面是详细的攻略。 1. axios post提交formdata的基本语法 在使用axios提交formdata时,需要使用FormData类来创建一个表单对象。具体语法如下: const formData = new FormData() formData.append(‘name1’, ‘value1’) formData.append(‘name2’…

    Vue 2023年5月28日
    00
  • 基于Vue实现timepicker

    基于Vue实现timepicker的完整攻略如下: 1. 安装依赖 在项目中安装Vue.js和element-ui依赖 npm install vue npm install element-ui 2. 创建组件 创建TimePicker组件并引入element-ui中的TimePicker组件 <template> <div> &l…

    Vue 2023年5月27日
    00
  • vue强制刷新组件的方法示例

    下面是对于 “vue强制刷新组件的方法示例” 的详细讲解攻略: Vue 强制刷新组件方法 在 Vue 中,当我们需要对组件进行强制刷新时,可以使用以下两种方式: 使用 key 属性 Vue 中,每个组件都可以设置一个 key 属性,当组件的 key 值改变时,组件会被强制重新渲染。 例如, <template> <div> <b…

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