手写 vue 源码 ===:自定义调度器、递归调用规避与深度代理
目录
引言
自定义调度器(Scheduler)
什么是调度器?
调度器的实现原理
自定义调度器的实际应用
切面编程(AOP)思想在调度器中的应用
递归调用规避
递归调用的问题
Vue 如何规避递归调用
深度代理(Deep Proxy)
什么是深度代理?
Vue 中的深度代理实现
bind 方法的应用
bind 方法的作用
为什么需要 bind?
总结
引言
在上一篇文章中,我们深入探讨了 Vue 响应式系统中的依赖清理机制。本文将继续深入 Vue 响应式系统的其他高级特性,包括自定义调度器、递归调用规避、深度代理等,并探讨其中涉及的bind
方法、切面编程思想以及递归实现流程。
自定义调度器(Scheduler)
什么是调度器?
调度器是 Vue 响应式系统中的一个重要概念,它允许我们控制 effect 的执行时机和方式。当响应式数据发生变化时,默认情况下会立即触发相关的 effect 执行。而通过自定义调度器,我们可以改变这一默认行为。
调度器的实现原理
在 Vue 的响应式系统中,调度器是通过 effect
函数的第二个参数传入的:
export function effect(fn, options: any = {}) {// 创建一个 effect 只要依赖的属性变化,就会重新执行const _effect = new ReactiveEffect(fn, () => {_effect.run();});// 执行_effect.run();if (options) {Object.assign(_effect, options); //用用户传入的配置,来覆盖默认的配置}const runner = _effect.run.bind(_effect); //bind 改变this指向 并且返回一个函数runner.effect = _effect; //将effect挂载到runner上return runner;
}
当我们创建一个ReactiveEffect
实例时,可以传入一个调度器函数作为第二个参数。当响应式数据变化触发 effect 执行时,会先检查是否有调度器,如果有则执行调度器而不是直接执行 effect:
export function triggerEffects(dep) {for (let effect of dep.keys()) {// 如果不是正在执行,那么就执行调度器if (!effect._runing) {if (effect.scheduler) {effect.scheduler();}}}
}
自定义调度器的实际应用
让我们看一个实际的例子,展示如何使用自定义调度器:
//调度器
let runner = effect(() => {document.body.innerHTML = `<h1>${state.flag ? state.name : state.age}</h1>`
}, {scheduler: () => {console.log('scheduler执行了,不自动更新');//AOP 面向切面编程runner() //重新渲染}
})
在这个例子中,我们创建了一个 effect 并传入了一个自定义调度器。当响应式数据变化时,不会直接执行 effect 的回调函数,而是先执行调度器函数。在调度器函数中,我们可以决定是否执行 effect,或者何时执行 effect。
切面编程(AOP)思想在调度器中的应用
上面的例子中提到了 AOP(面向切面编程)。AOP 是一种编程范式,它允许我们在不修改原有代码的情况下,通过"切面"的方式添加新的行为。
在 Vue 的响应式系统中,调度器就是一个典型的 AOP 应用:
- 原始行为:响应式数据变化时执行 effect
- 切面:调度器函数
- 新行为:响应式数据变化时先执行调度器,由调度器决定何时执行 effect
这种设计使得我们可以在不修改 Vue 核心代码的情况下,灵活地控制 effect 的执行方式,例如:
- 延迟执行 effect(使用
setTimeout
) - 批量执行 effect(收集多个变化后一次性执行)
- 条件执行 effect(根据某些条件决定是否执行)
递归调用规避
递归调用的问题
在响应式系统中,如果在 effect 中修改了触发该 effect 的响应式数据,就会导致递归调用,例如:
effect(() => {state.count = state.count + 1
})
这段代码会导致无限循环:读取 state.count
会收集依赖,修改 state.count
会触发依赖执行,而依赖执行又会修改 state.count
,如此循环往复。
Vue 如何规避递归调用
Vue 通过在ReactiveEffect
类中添加一个_runing
标志来规避递归调用:
class ReactiveEffect {_trackId = 0; // 当前的 effect 执行了几次deps = []; // 当前的 effect 依赖了哪些属性_depsLength = 0; // 当前的 effect 依赖的属性有多少个_runing = 0; // 当前的 effect 是否在执行public active = true; //默认是响应式的constructor(public fn, public scheduler) {}run() {// 如果当前状态是停止的,执行后,啥都不做if (!this.active) {return this.fn();}let lastEffect = activeEffect;try {activeEffect = this; // 当前的 effect 「依赖收集」// 每次执行前需要将上一次的依赖清空 effect.depspreCleanEffect(this);this._runing++; //执行前,将当前的effect设置为正在执行return this.fn(); //依赖收集 「state.name ,state.age」} finally {this._runing--; //执行后,将当前的effect设置为未执行postCleanEffect(this);activeEffect = lastEffect; // 执行完毕后 恢复上一次的 activeEffect}}
}
在 run 方法中,执行前将 _runing 设为 1,执行后将 _runing 设为 0。在 triggerEffects 函数中,会检查 effect 是否正在执行,如果是则不触发:
export function triggerEffects(dep) {for (let effect of dep.keys()) {// 如果不是正在执行,那么就执行调度器if (!effect._runing) {if (effect.scheduler) {effect.scheduler();}}}
}
深度代理(Deep Proxy)
什么是深度代理?
深度代理是指不仅对对象本身进行代理,还对对象的嵌套属性(如果是对象)也进行代理。这样,无论访问对象的哪一层属性,都能触发依赖收集和更新。
Vue 中的深度代理实现
Vue 的深度代理是在 getter 中实现的:
export const mutableHandlers: ProxyHandler<any> = {get(target: any, key: any, receiver: any) {// 如果访问的是代理对象的属性,直接返回if (key === ReactiveFlags.IS_REACTIVE) {return true;}// 依赖收集「收集这个对象上的这个属性,和 effect 关联」// 「当取值的时候,应该让 响应式属性,和 effect 建立联系」track(target, key);let res = Reflect.get(target, key, receiver); // 等价于receiver[key]if (isObject(res)) {// 如果取值是对象,则递归代理return reactive(res);}return res;},
}
深度代理的递归流程如下:
- 调用 reactive(obj) 创建一个代理对象
- 当访问代理对象的属性时,触发 get 方法
- 在 get 方法中,先进行依赖收集
- 然后获取属性值 res
- 如果 res 是一个对象,则调用 reactive(res) 对其进行代理
- 返回代理后的对象
这样,当我们访问嵌套属性时,例如 state.address.city,会发生以下过程:
- 访问 state.address,触发 state 的 get 方法
- 在 get 方法中,获取 address 属性,发现它是一个对象,调用 reactive(address) 创建代理
- 返回 address 的代理对象
- 访问 address 代理对象的 city 属性,触发 address 代理对象的 get 方法
- 在 get 方法中,获取 city 属性,它不是对象,直接返回
通过这种递归的方式,Vue 实现了对嵌套对象的深度代理。
// 深度监听
effect(() => {document.body.innerHTML = state.address.city
})setTimeout(() => {state.address.city = "上海"
}, 1000)
在这个例子中,我们创建了一个 effect,它依赖于 state.address.city。当我们修改 state.address.city 时,effect 会重新执行,更新页面内容。
这是因为 state.address 是一个代理对象,当我们访问 state.address.city 时,会触发 state.address 的 get 方法,从而收集依赖。当我们修改 state.address.city 时,会触发
state.address 的 set 方法,从而触发依赖更新。
bind 方法的应用
在 Vue 的响应式系统中,bind
方法被用于创建 effect 的运行器(runner)
export function effect(fn, options: any = {}) {// 创建一个 effect 只要依赖的属性变化,就会重新执行const _effect = new ReactiveEffect(fn, () => {_effect.run();});// 执行_effect.run();if (options) {Object.assign(_effect, options); //用用户传入的配置,来覆盖默认的配置}const runner = _effect.run.bind(_effect); //bind 改变this指向 并且返回一个函数runner.effect = _effect; //将effect挂载到runner上return runner;
}
bind 方法的作用
bind 方法是 JavaScript 中函数对象的一个方法,它创建一个新函数,该函数的 this 被绑定到指定的值。在 Vue 的响应式系统中, bind 方法的作用是:
- 创建一个新函数 runner,它的 this 被绑定到 _effect
- 这样,无论在哪里调用 runner,它内部的 this 都指向 _effect
- 这确保了 runner 可以正确地访问 _effect 的属性和方法
为什么需要 bind?
在 JavaScript 中,函数的 this 值取决于函数的调用方式,而不是函数的定义方式。如果我们直接返回 _effect.run,那么当调用这个函数时,this 可能不指向 _effect,导致错误。
通过使用 bind,我们确保了无论如何调用 runner,它内部的 this 都指向 _effect,从而保证了函数的正确执行。
总结
本文深入探讨了 Vue 响应式系统的几个高级特性:
- 自定义调度器:通过调度器,我们可以控制 effect 的执行时机和方式,实现更灵活的响应式行为。这是 AOP(面向切面编程)思想在 Vue 中的一个应用。
- 递归调用规避:Vue 通过在 effect 执行前后设置标志位,避免了在 effect 中修改响应式数据导致的递归调用问题。
- 深度代理:Vue 通过在 getter 中递归调用 reactive 函数,实现了对嵌套对象的深度代理,使得无论访问对象的哪一层属性,都能触发依赖收集和更新。
- bind 方法的应用:Vue 使用 bind 方法创建 effect 的运行器,确保了无论在哪里调用运行器,它内部的
this
都指向正确的 effect 实例。
通过理解这些高级特性,我们可以更深入地理解 Vue 响应式系统的工作原理,以及如何利用这些特性构建更高效、更灵活的 Vue 应用。
在实际开发中,虽然我们可能不需要直接操作这些底层 API,但了解它们的工作原理,可以帮助我们更好地理解 Vue 的响应式系统,以及在遇到复杂问题时进行调试和优化。
相关文章:
手写 vue 源码 ===:自定义调度器、递归调用规避与深度代理
目录 引言 自定义调度器(Scheduler) 什么是调度器? 调度器的实现原理 自定义调度器的实际应用 切面编程(AOP)思想在调度器中的应用 递归调用规避 递归调用的问题 Vue 如何规避递归调用 深度代理(D…...
WPF实时调试的一种实现方法
在WPF程序中,如果我们需要对程序进行调试,一般是使用断点/单步或输出日志之类的调试方法。 如果我们需要实时查看程序输出,可以将程序的输出类型修改为控制台应用程序 这样我们在程序运行后,就可以得到一个控制台窗口。 然后再配…...
数据库操作
本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. 🤭🤭🤭可能说的不是那么严谨.但小编初心是能让更多人能接…...
学习笔记:数据库——事务
1.内容: 基于现有数据库设计检查点实验,观察比较提交前后执行结果并分析。 2.实现 源码 -- 开启事务 START TRANSACTION;-- 插入一条订单记录(客户ID为10002) INSERT INTO orders (o_date, c_id) VALUES (NOW(), 10002);-- 获…...
企业级可观测性实现:OpenObserve云原生平台的本地化部署与远程访问解析
文章目录 前言1. 安装Docker2. 创建并启动OpenObserve容器3. 本地访问测试4. 公网访问本地部署的OpenObserve4.1 内网穿透工具安装4.2 创建公网地址 5. 配置固定公网地址 前言 嘿,各位小伙伴们,今天要给大家揭秘一个在云原生领域里横扫千军的秘密法宝—…...
【Linux系统】第三节—权限
Hello,好久不见—— 云边有个稻草人-CSDN个人博客主页 Linux-本节文章所属专栏-欢迎订阅-持续更新中~~~ 目录 hi!在这里—本节课重要知识点详解 一、Shell命令以及运行原理 二、Linux权限 2.1 Linux权限的概念 2.2 Linux权限管理 2.3 ⽂件权限值的…...
@Data和 @NoArgsConstructor注解详解
Data 和 NoArgsConstructor 注解详解 1. Data 注解 作用:Data 是 Lombok 提供的一个复合注解,用于自动生成 Java 类的常用方法,减少样板代码。生成的内容: Getter 和 Setter:为所有非静态、非 final 字段生成 getter…...
《云计算》第三版总结
《云计算》第三版总结 云计算体系结构 云计算成本优势 开源云计算架构Hadoop2.0 Hadoop体系架构 Hadoop访问接口Hadoop编程接口 Hadoop大家族 分布式组件概述ZooKeeperHbasePigHiveOozieFlumeMahout 虚拟化技术 服务器虚拟化存储虚拟化网络虚拟化桌面虚拟化OpenStack开源虚…...
滚珠导轨:电子制造领域精密运动的核心支撑
电子制造正朝着高精度、高效率方向飞速发展,滚珠导轨在这一进程中扮演着重要角色。滚珠导轨在电子制造领域中具有广泛且重要的应用,主要体现在以下几个方面: 1、印刷电路板(PCB)制造设备:滚珠导轨在PCB制造…...
Spark缓存--cache方法
在Spark 中,cache() 是用于优化计算性能的核心方法之一,但它有许多细节需要深入理解。以下是关于 cache() 的详细技术解析: 1. cache() 的本质 简化的 persist():cache() 是 persist(StorageLevel.MEMORY_ONLY) 的快捷方式&#x…...
kafka logs storage
Kafka 会将日志文件按段(Segment)存储。 Segment是Kafka的最小存储单元,它是一个可追加的文件,用于存储Kafka分区中的一部分消息。 在文件系统中,Partition 是目录名,而Segment 是文件名。 Segment可以通过…...
数据分析平台选型与最佳实践:如何打造高效、灵活的数据生态?
数据分析平台选型与最佳实践:如何打造高效、灵活的数据生态? 在大数据时代,数据分析平台已经成为企业决策的核心支撑。从传统 BI(商业智能)到现代 AI 驱动的数据分析,选择合适的平台不仅影响数据处理效率,也决定了企业的数字化竞争力。面对市场上的众多解决方案(如 Ap…...
MYSQL之索引结构,为何要用B+树
索引的目的就是为了提高查询效率 索引的结构是B树,那么说到B树,必须提一下其他三种结构,分别是:二叉查找树、平衡二叉树、B树 我们来看看各自的结构特征 二叉查找树 特点:任何节点的左子节点的值都小于当前节点的值,右…...
OpenCV 中用于背景分割的一个类cv::bgsegm::BackgroundSubtractorLSBP
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::bgsegm::BackgroundSubtractorLSBP 是 OpenCV 中用于背景分割的一个类,它基于局部样本二进制模式(Local Sample Bina…...
【PmHub后端篇】PmHub Gateway全局过滤器:接口调用耗时统计及黑白名单配置技术深度解析
在微服务架构日益成为现代应用开发主流模式的背景下,网关作为微服务架构前端的关键组件,肩负着路由请求、负载均衡、安全认证、流量控制、监控和日志记录等多项重要任务。本文将围绕PmHub项目中Gateway全局过滤器实现接口调用耗时统计的相关技术进行深入…...
国产激光二极管厂家
中国在激光二极管(Laser Diode)领域已有多家厂商布局,涵盖从低功率到高功率、不同波长的产品,应用于工业、医疗、通信、消费电子等领域。以下是部分国产激光二极管厂家及相关信息,供参考: 1. 武汉锐科光纤…...
安卓基础(XML)
123 属性行为适用场景注意事项match_parent填满父容器可用空间全屏视图、占满剩余空间父容器需有固定尺寸wrap_content根据内容自适应尺寸动态文本、图标、浮动按钮内容过长时可能超出父容器需处理 123 属性作用常用值…...
uniapp|获取当前用户定位、与系统设定位置计算相隔米数、实现打卡签到(可自定义设定位置、位置有效范围米数)
基于UniApp阐述移动应用开发中定位功能的实现全流程,涵盖实时定位获取、动态距离计算与自定义位置、有效范围设定等功能。文章提供完整的代码示例与适配方案,适用于社交签到、课堂教室打卡等场景。 目录 引言定位功能在移动应用中的价值(社交、导航、O2O等场景)UniApp跨平台…...
matlab稳定求解高精度二维对流扩散方程
利用MATLAB稳定求解高精度二维对流扩散方程 Diffusion_1D.m , 2310 Diffusion_2D.m , 3813 license.txt , 1334...
【最新版】likeshop连锁点餐系统-PHP版+uniapp前端全开源
一.系统介绍 likeshop外卖点餐系统适用于茶饮类的外卖点餐场景,搭建自己的一点点、奈雪、喜茶点餐系统。 系统基于总部多门店的连锁模式,拥有门店独立管理后台,支持总部定价和门店定价LBS定位点餐,可堂食可外卖。无论运营还是二开…...
Redis 重回开源怀抱:开源精神的回归与未来展望
在开源软件的广袤天地里,Redis 一直是备受瞩目的明星项目。近期,Redis 宣布重新回归开源,这一消息犹如一颗石子投入平静的湖面,在技术社区激起层层涟漪。今天,就让我们深入了解 Redis 这一重大转变背后的故事、意义以及…...
mac运行java文件提示 错误: 缺少 JavaFX 运行时组件, 需要使用该组件来运行此应用程序
1、问题如上 双击java文件打不开,命令行报错。查找了下文章说java8之后,高版本jdk不自带javafx,需要自己下载 2、解决办法 首先查看自己的java版本,我是17.0.10 访问 JavaFX - Gluon 下载对应的版本,如果没有对应的 …...
pimpl与unique_ptr的问题
PImpl与std::unique_ptr组合 pimpl(Pointer to Implementation)是C程序开发中非常常用的技巧之一,它的好处有: 节省程序编译时间保持程序/库的二进制兼容性隐藏实现细节 举例一个常见的pimpl的使用示例: // a.h class Impl; //前置声明 c…...
Opencv进阶操作:图像拼接
文章目录 前言一、图像拼接的原理1. 特征提取与匹配2. 图像配准3. 图像变换与投影4. 图像融合5. 优化与后处理 二、图像拼接的简单实现(案例实现)1.引入库2.定义cv_show()函数3.创建特征检测函数detectAndDescribe()4.读取拼接图片5.计算图片特征点及描述…...
记录Token反序列化OAuth2Authentication(主要是直接存储用户信息的UserDetails )
项目场景: 本地开发环境部署了多套系统,并且使用了同一套登入鉴权组件,存入的TokenStore也是相同的Redis库; 问题描述&原因分析 由于是做的不同项目,group等组织机构不同,导致多系统若是有存储相同用…...
【QT】深入理解 Qt 中的对象树:机制、用途与最佳实践
深入理解 Qt 中的对象树:机制、用途与最佳实践 在使用 Qt 编程时,你是否注意到很多对象可以设置“父对象”?比如: QPushButton* btn new QPushButton(parentWidget);这不是简单的层级结构,而是 Qt 强大而优雅的 对象…...
基于FPGA的血氧和心率蓝牙监测系统设计-max30102
文章目录 前言一、芯片手册分析二、串口接口的血氧模块使用讲解三、仿真时序分析四、代码分析1.蓝牙数据发送2.心率数据采集 总结 前言 本产品的核心是基于心率传感器的智能心率监测系统,通过硬件端的心率传感器获取人体的心率和血氧浓度等信息,并进行实…...
华为首款鸿蒙电脑正式亮相,开启国产操作系统新篇章
5 月 8 日,华为在深圳举办鸿蒙电脑技术与生态沟通会,正式推出了备受瞩目的首款鸿蒙电脑,这一重大举措标志着国产操作系统在个人电脑(PC)领域实现了关键突破,为行业发展注入了新的活力。 历经五年打磨&…...
Docker部署常见应用之Superset
文章目录 使用 Docker 部署使用 Docker Compose 部署参考文章 以下是使用 Docker 部署 Superset 并将存储配置为 MySQL 的详细步骤: 使用 Docker 部署 获取Superset镜像: 使用Docker从官方仓库拉取Superset镜像:docker pull apache/superset:4.0.0创建 …...
触想CX-3588工控主板应用于移动AI数字人,赋能新型智能交互
一、行业发展背景 随着AI智能、自主导航和透明屏显示等技术的不断进步,以及用户对“拟人化”、“沉浸式”交互体验的期待,一种新型交互终端——“移动AI数字人”正在加速实现规模化商用。 各大展厅展馆、零售导购、教学政务甚至家庭场景中,移…...
关系代数操作之复杂扩展操作
除(Division) 定义:关系R为n度关系,关系S为m度关系,m<n,记作RS,关系是K(n-m)度关系 数学描述: 相当于(RS)*S在R中的元组 外连接(…...
STM32G070xx将Flash页分块方式存储,固定数据块存储,实现一次擦除多次写入
STM32G070xx将Flash页分块方式存储,固定数据块存储,实现一次擦除多次写入 参考例程例程说明一、存储区数据结构二、读取存储区数据三、写入存储区数据四、测试函数五、测试结果 参考例程 STM32G0xx使用LL库将Flash页分块方式存储数据实现一次擦除可多次…...
V4L2应用程序开发-- 控制流程
使用摄像头时,我们可以调整很多参数,比如: 对于视频流本身: 设置格式:比如V4L2_PIX_FMT_YUYV、V4L2_PIX_FMT_MJPEG、V4L2_PIX_FMT_RGB565 设置分辨率:1024*768等 对于控制部分: 调节亮度 调…...
《大数据技术之Scala》
这是一篇关于大数据技术中Scala语言的基础教程文章,主要介绍了Scala语言的发展历史、与Java的关系、语言特点、环境搭建、插件安装、编程基础、变量和数据类型、运算符、流程控制、函数式编程、面向对象编程、集合操作、模式匹配、异常处理、隐式转换和泛型等核心内…...
使用thymeleaf模版导出swagger3的word格式接口文档
1.pom配置 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.8.RELEASE</version></parent><properties><skipTests>true</skipTests&g…...
Android RecyclerView自带的OnFlingListener,Kotlin
Android RecyclerView自带的OnFlingListener,Kotlin Android启动应用时屏蔽RecyclerView滑动,延时后再允许滑动,Kotlin-CSDN博客 使用了GestureDetectorRecyclerView的setOnTouchListener检测用户的快滑fling事件。发现RecyclerView也自带了监…...
STM32+安信可Ai-WB2-12F连接阿里云物联网平台
第一步:在阿里云物联网平台创建设备 具体操作流程如下 第二步:生成个人client_id,用户名和密码 打开该软件sign.html 将刚才复制的信息粘贴进去 生成自己的client_id,用户名和密码 第三步:打开MQTTfx软件 电机connect旁边的配置࿰…...
Python实现中文数字与阿拉伯数字映射生成器(支持0-9999)
文章目录 1. 引言2. 需求分析3. 核心实现思路4. 完整代码实现 1. 引言 在中文文本处理和自然语言处理(NLP)应用中,经常需要将中文数字转换为阿拉伯数字。本文将介绍如何使用Python根据用户从控制台输入的数字范围,生成相应的中文数字到阿拉伯数字…...
链表的面试题4之合并有序链表
这篇文章我们继续来讲链表中很经典的面试题:合并有序链表。 目录 迭代 递归 我们首先来看一下这张图片里面的要求,给你两个链表,要求把他们按照从小到大的方式排列。 这里涉及到几个问题,首先,我们的头节点是不是要…...
CTF - PWN之ORW记录
CTF - Pwn之ORW记录https://mp.weixin.qq.com/s/uiRtqCSopn6U6NqyKJ8I7Q...
mission planner烧录ardupilot固件报错死机
问题 烧录自己编译的固件,upload done成功后,又跳出以下提示 ,返回重新烧录仍然报错 解决 先烧录官方稳定的固件然后使用mission planner连接,此时可能会反复识别串口,因为会死机反复重启,导致灯闪烁又…...
单片机嵌入式滤波算法库
kw_ucFiltering库说明 本科针对常用的滤波算法进行汇总,主要包括: 一阶滤波算法 平滑滤波 中位值滤波 限幅 卡尔曼滤波 截至目前(20250508)滤波算法持续更新中。 本库开源连接地址:gitee连接 一阶滤波算法实现 原理…...
CAS、CAS自旋、CAS自旋锁、CLH锁与Java AQS:深入理解并发编程核心机制
CAS、CAS自旋、CAS自旋锁、CLH锁与Java AQS:深入理解并发编程核心机制 1. CAS(Compare and Swap) 什么是CAS? CAS(Compare and Swap)是一种无锁(Lock-Free)的原子操作,…...
《运维那些事儿》专栏总目录(持续更新)
《运维那些事儿》专栏以Linux系统为基础,分享作者十年运维生涯中运用到的关键技术要点。本专栏涵盖消息中间件、数据中间件、数据库、虚拟化、Web服务器、高可用架构等运维工作中涉及到的相关内容,每周持续交叉更新一篇高质量技术博文。学生可用于了解、…...
鸿蒙NEXT开发动画案例4
1.创建空白项目 2.Page文件夹下面新建Spin.ets文件,代码如下: /*** TODO SpinKit动画组件 - 双粒子旋转缩放动画* author: CSDN-鸿蒙布道师* since: 2025/05/08*/ ComponentV2 export struct SpinFour {// 参数定义Require Param spinSize: number 36…...
【Linux学习笔记】基础IO之理解文件
【Linux学习笔记】基础IO之理解文件 🔥个人主页:大白的编程日记 🔥专栏:Linux学习笔记 前言 哈喽,各位小伙伴大家好!上期我们讲了进程替换 今天我们讲的是基础IO之理解文件。话不多说,我们进入正题&#…...
动态计算el-table高度
form、搜索框、底部导航栏设置class <el-table :height"tableHeight" /> // 计算表格高度的计算属性 const tableHeight ref(0); proxy.toTableHeight((res)>{tableHeight.value res; });tableHeight.js import { nextTick } from vue;export fun…...
【Linux系列】目录大小查看
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
数据结构*二叉树
树 树是一种非线性数据结构。 这就是抽象的树的结构。 对于一棵树来说,有N个结点,就有N-1条边 其中有许多概念: 根结点:对于上图来说就是A 子树:就是结点下面分开的部分。例如:A的子树就是以B为根结点的…...
RESTful
一:简介 定义 (1)访问网络资源的格式 (2)优点 (3)区分操作 (4)注意事项...