首页 > 其他分享 >Vue 3.0 reactive/effect

Vue 3.0 reactive/effect

时间:2023-07-05 18:45:02浏览次数:47  
标签:Vue return target effect reactive key const

reactive.js:

import { isObject } from "../utils";
import { track, trigger } from "./effect";

export function reactive(target) {
    // 判断 target 类型
    // 如果是基本类型,则不将其转化成响应式
    if (!isObject(target)) return target;

    const proxy = new Proxy(target, {
        get(target, key, receiver) {
            const res = Reflect.get(target, key, receiver);
            
            // 收集依赖
            track(target, key);
            
            return res;
        },
        set(target, key, value, receiver) {
            const res = Reflect.get(target, key, value, receiver);
            
            // 触发依赖
            trigger(target, key);
            
            return res;
        }
    });

    return proxy;
}

 

effect.js:

// 记录当前正在执行的副作用函数
let activeEffect;

/** 难点
 * 一个副作用函数可能依赖多个响应式数据
 * 一个响应式数据更新可能会触发多个副作用函数
 * 因此 targetMap 的结构是:
 * {
 *      [target]: {
 *          [key]: []
 *      }
 * }
 * 使用 WeakMap 是因为不需要手动删除不需要的依赖
 */ 
const targetMap = new WeakMap();

export function effect(fn) {
    const effectFn = () => {
        try {
            activeEffect = effectFn;
            return fn();
        } finally {
            // todo
        }
    }

    effectFn();
    return effectFn;
}

export function track(target, key) {
    if (!activeEffect) return;

    let depsMap = targetMap.get(target);
    
    // 初始化时一定是不存在的
    if (!depsMap) targetMap.set(target, (depsMap = new Map()));

    let deps = depsMap.get(key);
    // 同样,初始化的时候一定无值
    if (!deps) depsMap.set(key, (deps = new Set()));

    deps.add(activeEffect);

    console.log(targetMap, key)
}

export function trigger(target, key) {
    const depsMap = targetMap.get(target);

    if (!depsMap) return;

    const deps = depsMap.get(key)
    
    if (!deps) return;

    deps.forEach(effectFn => {
        effectFn();
    });
}

 

index.js(入口文件):

import { reactive } from "./reactive/reactive";
import { effect } from "./reactive/effect";

const observed = reactive({
    count: 0
});

effect(() => {
    console.log(observed.count)
})

 

标签:Vue,return,target,effect,reactive,key,const
From: https://www.cnblogs.com/cc-freiheit/p/17529543.html

相关文章

  • 基于vue-cli 5 和webpack 5实现微前端
    有这么一个需求,项目里有很多业务模块,它们都有引用一些公共组件,每个业务模块打包后都是一个独立的应用,当公共组件修改时,单独打包公共组件,其他应用能够不需要重新构建,就能直接使用最新的公共组件,要怎么实现?一开始我想到的是使用网络资源,就是把公共组件打包后的js文件放到服务器,其他......
  • 向AI请教能否用图片生成vue代码
    Canfigmageneratevuecodebasedonascreenshotcapturedfromanandroidapp?Wed,Jul5,2023,3:49pmavatarNo,FigmadoesnotnativelygenerateVuecodebasedonascreenshotcapturedfromanAndroidapp.Figmaisprimarilyadesignandprototyping......
  • 10:vue3 组件注册方式(全局注册和局部注册)
    组件注册方式一个Vue组件在使用前需要先被“注册”,这样Vue才能在渲染模板时找到其对应的实现。组件注册有两种方式:全局注册和局部注册。全局注册将09节课程的Header组件进行全局注册演练在main.js中添加Header.vue组件的注册1import{createApp}from'vue'2impo......
  • vue3子组件向父组件传参
    《好记性不如烂笔头系列》子组件<template><divclass="protocolstyle"><van-checkboxv-model="checked"toggle@click="userProtocolClick"></van-checkbox><spanclass="marginL5">测试数据</span......
  • VUE 2项目使用vue-json-excel导出数据
    记录一下后端返回的json数据转成excel导出这里外面使用的是vue-json-excel1.安装包npminstallvue-json-excel2.组件中使用<download-excelclass="btnbtn-default":data="json_data":fields="json_fields"worksheet="MyWorksheet"name=&......
  • 09: vue3 组件嵌套关系
    组件嵌套关系组件允许我们将UI划分为独立的、可重用的部分,并且可以对每个部分进行单独的思考。在实际应用中,组件常常被组织成层层嵌套的树状结构:这和我们嵌套HTML元素的方式类似,Vue实现了自己的组件模型,使我们可以在每个组件内封装自定义内容与逻辑。创建组件及引用关系......
  • vue-treeselect 被 overflow 遮挡
    场景在一个内容区域设置了overflow纵向滚动的对话框中,内部的vue-treeselect组件下拉框选项被遮挡了。解决办法给vue-treeselect设置appendToBody和z-index属性。注意事项设置了appendToBody后,下拉框选项的字号会变大。为了与原来的字号相匹配,需要修改样式。找......
  • 在asp.net core中使用vue3+vite(起)
    前言一开始是一个自用的应用,原本是用razor写的。最近有了点新想法,加点新功能,但是我接触的项目基本都是vue+api的前后端分离,用这razor写的是真不习惯,最后决定还是用习惯的vue重写。之前尝试过在.netcore里使用vue2+webpack,毕竟实际上就是把.vue翻译成了.js来用,一个站点就能跑。......
  • 第八篇 - Vue路由跳转步骤
    第六篇讲了将SpringBoot和Vue项目结合起来,实现了使用Vue访问SpringBoot的API。这一篇我们介绍当访问API成功后跳转到新的Vue页面怎么处理。参考链接:https://zhuanlan.zhihu.com/p/468467076第一步:首先新建一个Vue页面 jump1test.vue/*eslint-disable*/<template><div......
  • 08:vue3 组件基础
    定义一个组件在components文件夹下新建MyComponent.vue组件 写入下面代码1<script>2exportdefault{3data(){4return{5count:06}7}8}9</script>1011<template>12<button@click="count++">我被点击了{......