当前位置: 首页 > news >正文

Vue3响应式源码实现

Vue3响应式源码实现

初始化项目结构

vue-proxy
├── effect.js
├── effect.ts
├── index.html
├── index.js
├── package.json
├── reactive.js
├── reactive.ts
└── webpack.config.js

reactive.ts

import { track, trigger } from "./effect"// 判断是否是对象
const isObject = (target) => target !== null && typeof target === "object"// 泛型约束只能传入Object类型
export const reactive = <T extends object>(target: T) => {return new Proxy(target, {get(target, key, receiver) {console.log(target);console.log(key);console.log(receiver);let res = Reflect.get(target, key, receiver)track(target, key)if (isObject(res)) {return reactive(res)}return res},set(target, key, value, receiver) {let res = Reflect.set(target, key, value, receiver)console.log(target, key, value);trigger(target, key)return res}})}

effect.ts

// 更新视图的方法
let activeEffect;
export const effect = (fn: Function) => {const _effect = function () {activeEffect = _effect;fn()}_effect()
}// 收集依赖
const targetMap = new WeakMap()
export const track = (target, key) => {let depsMap = targetMap.get(target)if (!depsMap) {depsMap = new Map()targetMap.set(target, depsMap)}let deps = depsMap.get(key)if (!deps) {deps = new Set()depsMap.set(key, deps)}deps.add(activeEffect)
}// 触发更新
export const trigger = (target, key) => {const depsMap = targetMap.get(target)const deps = depsMap.get(key)deps.forEach(effect => effect())
}

测试

执行 tsc 转成 js 代码,没有 tsc 的全局安装 typescript

npm install typescript -g

新建 index.js,分别引入 effect.jsreactive.js

import { effect } from "./effect.js";
import { reactive } from "./reactive.js";let data = reactive({name: "lisit",age: 18,foor: {bar: "汽车"}
})effect(() => {document.getElementById("app").innerText = `数据绑定:${data.name} -- ${data.age} -- ${data.foor.bar}`
})document.getElementById("btn").addEventListener("click", () => {data.age++
})

新建index.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><div id="app"></div><button id="btn">按钮</button>
</body>

然后再根目录执行

npm init -y

安装依赖

npm install webpack webpack-cli webpack-dev-server html-webpack-plugin -D

然后新建 webpack.config.js

const path = require("path")
const HtmlWebpakcPlugin = require("html-webpack-plugin")module.exports = {entry: "./index.js",output: {path: path.resolve(__dirname, "dist")},plugins: [new HtmlWebpakcPlugin({template: path.resolve(__dirname, "./index.html")})],mode: "development",// 开发服务器devServer: {host: "localhost", // 启动服务器域名port: "3000", // 启动服务器端口号open: true, // 是否自动打开浏览器},
}

执行命令启动项目

npx webpack serve

image-20230904232457817

image-20230904232522425

http://www.lryc.cn/news/160720.html

相关文章:

  • 【RapidAI】P1 中文文本切割程序
  • 4、QT中的网络编程
  • 单例模式(饿汉式单例 VS 懒汉式单例)
  • Oracle数据库连接之TNS-12541异常
  • sql中的排序函数dense_rank(),RANK()和row_number()
  • Flask狼书笔记 | 05_数据库
  • HJ70 矩阵乘法计算量估算
  • Doris数据库使用记录
  • 华为OD机试真题【篮球比赛】
  • sublime text 格式化json快捷键配置
  • Spring Cloud 面试题总结
  • 如何实现24/7客户服务自动化?
  • 2022年12月 C/C++(六级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • 【Spring Cloud系列】 雪花算法原理及实现
  • Postgresql 阿里云部署排雷
  • l8-d10 TCP协议是如何实现可靠传输的
  • 9月9日扒面经
  • 项目实战:ES的增加数据和查询数据
  • vs code调试rust乱码问题解决方案
  • 大数据课程K22——Spark的SparkSQL的API调用
  • 数据结构学习系列之顺序表的两种删除方式
  • 机器学习笔记之最优化理论与方法(七)无约束优化问题——常用求解方法(上)
  • ES-索引管理
  • linux中常用shell脚本整理
  • 介绍PHP
  • selenium+find_elements用法
  • 1DM+下载器_11.2.1魔改增强版下载
  • vue3:3、项目目录和关键文件
  • ChatGPT实战与私有化大模型落地
  • 10分钟从实现和使用场景聊聊并发包下的阻塞队列