手撸vue3核心源码——响应式原理(scheduler以及onStop)

简介: 手撸vue3核心源码——响应式原理(scheduler以及onStop)

image.png

编辑

scheduler

scheduler(调度),我们函数的执行需要调度控制,它就相当于一个开关,来把控是否要执行fn,当我们传入了scheduler时,就不会去执行fn了,我们先来写个单元测试,来把理想的功能写一下

image.png

编辑

这里当我们obj.foo++时会触发effect函数执行,但是我们传入了scheduler,所以fn不会再走了,而是去执行scheduler ,因此dummy = obj.foo这里的逻辑走不了,所以dummy的值不会更新

我们来改动一下effect, 这里为什么要用Object.assign()为依赖项绑定options呢,因为我们再执行依赖性的时候要根据options上的属性来控制,所以当trigger时,我们会检查一下options选项,所以要给_effect绑

复制代码

export function effect(fn, options: any = {}) {
    const _effect = new reactiveEffect(fn, options.schdeuler)
    // extend(_effect, options)
    Object.assign(_effect, options)
    _effect.run()
    const runner: any = _effect.run.bind(_effect)
    runner._effect = _effect
    return runner
}
class reactiveEffect {
    private _fn: any
    //用于将那个依赖存进去
    deps = []
    active = true
    constructor(fn, public schduler?: Function) {
        this._fn = fn
        this.schduler = schduler
    }
    run() {
        activeEffect = this
        return this._fn()
    }
    stop() {
        if (this.active) {
            this.active = false
            //这里存放的dep是set结构,所以需要delete来操作
            clearEffect(this)
        }
    }
}

export function trigger(target, key) {
    const depMap = targetMap.get(target)
    const deps = depMap.get(key)
    for (const dep of deps) {
        if (dep.scheduler) {
            dep.scheduler()
        } else {
            dep.run()
        }
    }
}

这样当我们有scheduler时,在依赖触发时就会调用scheduler而不是fn了,所以就实现了控制fn的调用


onStop

onStop是stop之后的回调函数,stop上节我们有讲到过, 调用stop之后我们依赖性会被清空,同时也不会再收集依赖, 这样就监听不了reactive对象的变化了,onStop也就是stop之后的回调,因此我们在stop函数中调用即可


class reactiveEffect {
    private _fn: any
    //用于将那个依赖存进去
    deps = []
    active = true
    onStop?: () => void
    constructor(fn, public schduler?: Function) {
        this._fn = fn
        this.schduler = schduler
    }
    run() {
        activeEffect = this
        return this._fn()
    }
    stop() {
        if (this.active) {
            this.active = false
            //这里存放的dep是set结构,所以需要delete来操作
            clearEffect(this)
            if (this.onStop) {
                this.onStop()
            }
        }
    }
}

到此就已经实现了scheduler以及onStop的功能了


写在最后

options其实还有很多配置项,这里挑最核心的内容来复现,直接看本篇章可能有些吃力,希望这次的博客工程能像连续剧一样让大家看得津津有味。

相关文章
|
24天前
|
API
vue3知识点:响应式数据的判断
vue3知识点:响应式数据的判断
27 3
|
28天前
|
缓存 JavaScript UED
优化Vue的响应式性能
【10月更文挑战第13天】优化 Vue 的响应式性能是一个持续的过程,需要不断地探索和实践,以适应不断变化的应用需求和性能挑战。
31 2
|
24天前
|
JavaScript 前端开发 API
vue3知识点:Vue3.0中的响应式原理和 vue2.x的响应式
vue3知识点:Vue3.0中的响应式原理和 vue2.x的响应式
24 0
|
8天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
8天前
|
存储 缓存 JavaScript
在 Vue 中使用 computed 和 watch 时,性能问题探讨
本文探讨了在 Vue.js 中使用 computed 计算属性和 watch 监听器时可能遇到的性能问题,并提供了优化建议,帮助开发者提高应用性能。
|
8天前
|
存储 缓存 JavaScript
如何在大型 Vue 应用中有效地管理计算属性和侦听器
在大型 Vue 应用中,合理管理计算属性和侦听器是优化性能和维护性的关键。本文介绍了如何通过模块化、状态管理和避免冗余计算等方法,有效提升应用的响应性和可维护性。
|
8天前
|
存储 缓存 JavaScript
Vue 中 computed 和 watch 的差异
Vue 中的 `computed` 和 `watch` 都用于处理数据变化,但使用场景不同。`computed` 用于计算属性,依赖于其他数据自动更新;`watch` 用于监听数据变化,执行异步或复杂操作。
|
8天前
|
JavaScript 前端开发 UED
vue学习第二章
欢迎来到我的博客!我是一名自学了2年半前端的大一学生,熟悉JavaScript与Vue,目前正在向全栈方向发展。如果你从我的博客中有所收获,欢迎关注我,我将持续更新更多优质文章。你的支持是我最大的动力!🎉🎉🎉
|
9天前
|
存储 JavaScript 开发者
Vue 组件间通信的最佳实践
本文总结了 Vue.js 中组件间通信的多种方法,包括 props、事件、Vuex 状态管理等,帮助开发者选择最适合项目需求的通信方式,提高开发效率和代码可维护性。
|
8天前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。自学前端2年半,熟悉JavaScript与Vue,正向全栈方向发展。博客内容涵盖Vue基础、列表展示及计数器案例等,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉