Svelte 最新中文文档教程(17)—— 生命周期钩子

news/2025/2/23 10:55:12/文章来源:https://www.cnblogs.com/yayujs/p/18731902

前言

Svelte,一个语法简洁、入门容易,面向未来的前端框架。从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1

image.png

Svelte 以其独特的编译时优化机制著称,具有轻量级高性能易上手等特性,非常适合构建轻量级 Web 项目,也是我做个人项目的首选技术栈。

目前 Svelte 基于 Svelte 5 发布了最新的官方文档,但却缺少对应的中文文档。为了帮助大家学习 Svelte,为爱发电翻译了官方文档。

我同时搭建了 Svelte 最新的中文文档站点:https://svelte.yayujs.com ,如果需要辅助学习,也可以入手我的小册《Svelte 开发指南》,语法篇、实战篇、原理篇三大篇章带你系统掌握 Svelte!

虽说是翻译,但个人并不喜欢严格遵守原文,为了保证中文阅读流畅,会删减部分语句,对难懂的部分也会另做补充解释,希望能给大家带来一个好的中文学习体验。

欢迎围观我的“网页版朋友圈”、加入“冴羽·成长陪伴社群”,踏上前端大佬成长之路。

生命周期钩子

在 Svelte 5 中,组件生命周期仅由两部分组成:创建和销毁。中间的一切,比如当某些状态更新时,与整个组件无关,只有需要对状态变化做出响应的部分才会得到通知。

这是因为在底层,变化的最小单位实际上并不是组件,而是组件在初始化时设置的(渲染)effects。因此,不存在"更新前"/"更新后"这样的钩子。

onMount

onMount 函数传入一个回调函数,在组件挂载到 DOM 后立即运行。它必须在组件初始化期间被调用(但不需要位于组件内部;可以从外部模块调用)。

onMount 不会在服务端渲染的组件中运行。

<script>import { onMount } from 'svelte';onMount(() => {console.log('组件已挂载');});
</script>

如果 onMount 返回一个函数,它将在组件卸载时被调用。

<script>import { onMount } from 'svelte';onMount(() => {const interval = setInterval(() => {console.log('beep');}, 1000);return () => clearInterval(interval);});
</script>

[!NOTE] 这种行为只在传递给 onMount 的函数同步返回值时才有效。async 函数总是返回一个 Promise,因此不能同步返回一个函数。

onDestroy

安排一个回调在组件卸载前立即运行。

```dts function onDestroy(fn: () => any): void; ```

onMountbeforeUpdateafterUpdateonDestroy 中,这是唯一一个在服务端组件内运行的。

<script>import { onDestroy } from 'svelte';onDestroy(() => {console.log('组件正在被销毁');});
</script>

tick

虽然没有"更新后"钩子,但你可以使用 tick 来确保在继续之前 UI 已更新。tick 返回一个 promise,该 promise 在所有待处理的状态更改被应用后 resolve,如果没有待处理的状态更改,则在下一个微任务中 resolve。

<script>import { tick } from 'svelte';$effect.pre(() => {console.log('组件即将更新');tick().then(() => {console.log('组件刚刚更新');});});
</script>

已废弃:beforeUpdate / afterUpdate

Svelte 4 有两个在组件整体更新前后运行的钩子。为了向后兼容,这些钩子在 Svelte 5 中被模拟实现,但在使用符文的组件中不可用。

<script>import { beforeUpdate, afterUpdate } from 'svelte';beforeUpdate(() => {console.log('组件即将更新');});afterUpdate(() => {console.log('组件刚刚更新');});
</script>

不要使用 beforeUpdate,应该使用 $effect.pre;不要使用 afterUpdate,应该使用 $effect — 这些符文提供更细粒度的控制,只对你实际关心的更改做出响应。

聊天窗口示例

我们来实现一个聊天窗口,当出现新消息时自动滚动到底部(前提是你已经滚动到底部了),我们需要在更新 DOM 之前先测量它。

在 Svelte 4 中,我们使用 beforeUpdate 来实现,但这是一个有缺陷的方法 — 它在每次更新前都会触发,无论是否相关。在下面的示例中,我们需要引入像 updatingMessages 这样的检查,以确保在有人切换暗黑模式时不会影响滚动位置。

使用符文,我们可以使用 $effect.pre,它的行为与 $effect 相同,但在 DOM 更新之前运行。只要我们在 effect 内明确引用 messages,它就会在 messages 改变时运行,而在 theme 改变时不会运行。

因此,beforeUpdate 以及同样麻烦的小伙伴 afterUpdate 在 Svelte 5 中已被废弃。

  • 之前
  • 之后
<script>import { ---beforeUpdate, afterUpdate,--- tick } from 'svelte';---let updatingMessages = false;---let theme = +++$state('dark')+++;let messages = +++$state([])+++;let viewport;---beforeUpdate(() => {---+++$effect.pre(() => {+++---if (!updatingMessages) return;---+++messages;+++const autoscroll = viewport && viewport.offsetHeight + viewport.scrollTop > viewport.scrollHeight - 50;if (autoscroll) {tick().then(() => {viewport.scrollTo(0, viewport.scrollHeight);});}---updatingMessages = false;---});function handleKeydown(event) {if (event.key === 'Enter') {const text = event.target.value;if (!text) return;---updatingMessages = true;---messages = [...messages, text];event.target.value = '';}}function toggle() {toggleValue = !toggleValue;}
</script><div class:dark={theme === 'dark'}><div bind:this={viewport}>{#each messages as message}<p>{message}</p>{/each}</div><input +++onkeydown+++={handleKeydown} /><button +++onclick+++={toggle}> 切换暗黑模式 </button>
</div>

Svelte 中文文档

本篇已收录在掘金专栏 《Svelte 中文文档》,该系列预计 40 篇。

系统学习 Svelte,欢迎入手小册《Svelte 开发指南》。语法篇、实战篇、原理篇三大篇章带你系统掌握 Svelte!

此外我还写过 JavaScript 系列、TypeScript 系列、React 系列、Next.js 系列、冴羽答读者问等 14 个系列文章, 全系列文章目录:https://github.com/mqyqingfeng/Blog

欢迎围观我的“网页版朋友圈”、加入“冴羽·成长陪伴社群”,踏上前端大佬成长之路。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/888297.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Java SE] FunctionInterface 注解: 函数式接口(JDK8+)

概述:FunctionInterface/函数式接口 简介函数式接口是指只包含一个抽象方法的接口,可以使用 Lambda 表达式来创建该接口的实例。@FunctionalInterface 注解是 Java Lang 包中的一个注解,用于标识一个接口是函数式接口。@FunctionalInterface 注解的作用:编译时检查:@Funct…

去中心化 AI:赋权还是混乱?

DeepSeek 如何在 AI 去中心化方面迈出了巨大的一步,以及为什么这比你想象的更重要Nadia Piet + AIxDESIGN & Archival Images of AI / Better Images of AI / AI Am Over It / CC-BY 4.02025 年 1 月 27 日星期一,DeepSeek —— 一家几乎凭空冒出来的中国初创公司 —— 发…

SmolLM2:多阶段训练策略优化和高质量数据集,小型语言模型同样可以实现卓越的性能表现

SmolLM2 采用创新的四阶段训练策略,在仅使用 1.7B 参数的情况下,成功挑战了大型语言模型的性能边界:在 MMLU-Pro 等测试中超越 Qwen2.5-1.5B 近 6 个百分点 数学推理能力(GSM8K、MATH)优于 Llama3.2-1B 在代码生成和文本重写任务中展现出色表现 支持 8K tokens 的长文本处…

2025.2.23 (java的学习)

。。。昨天星期六一整天都没学习。。做了一个哆啦a梦。✌附一个目前弄的哆啦a梦全家桶吧。

自动驾驶两个传感器之间的坐标系转换

有两种方式可以实现两个坐标系的转换。 车身坐标系下一个点p_car,需要转换到相机坐标系下,旋转矩阵R_car2Cam,平移矩阵T_car2Cam。点p_car在相机坐标系下记p_cam. 方法1:先旋转再平移 p_cam = T_car2Cam * p_car + T_car2Cam 需要注意的是,这里的平移矩阵T_car2Cam是车身坐…

8-2 MySQL 索引的设计原则(超详细说明讲解)

8-2 MySQL 索引的设计原则(超详细说明讲解) @目录8-2 MySQL 索引的设计原则(超详细说明讲解)1. 测试数据准备2. 哪些情况适合创建索引2.1 字段的数值有唯一性的限制2.2 频繁作为 WHERE 查询条件的字段2.3 经常 GROUP BY 和 ORDER BY 的列2.4 UPDATE、DELETE 的 中的WHERE 条件列…

北京时间同步

本地时间与北京时间 同步 参考:https://blog.csdn.net/qq_46092061/article/details/128748789 本地显示秒数while True:current_time = time.strftime("%H:%M:%S")if current_time >= "19:59:59":print("start")breaktime.sleep(0.5) # 减…

客流统计自动识别摄像头

客流统计自动识别摄像头提供了重要的决策依据。通过分析客流数据,商家可以了解顾客的消费习惯与高峰时段,从而优化营业时间、调整商品布局和促销策略。例如,如果某个时间段内顾客数量明显增加,商家可以考虑在此时推出促销活动,以吸引更多消费者。此外,通过长期的数据积累…

老人摔倒自动监控摄像头

老人摔倒自动监控摄像头通过智能识别技术,可以实时监测到老年人的活动状态。一旦系统检测到异常情况,比如老人摔倒,它会立即向家庭成员或护理人员发送警报。这种及时性大大提高了救助的效率,使得老人能够在最短时间内得到帮助。此外,一些先进的监控系统还配备了语音通话功…

在Odoo18.0中使用韵达速递

本文给大家带来的的是odoo与韵达速递的免费对接方案。 注册韵达开放平台 想要使用韵达速递,首先我们就需要注册一个韵达开放平台的账号,并创建一个开放平台应用。 创建完应用之后,我们需要以下4个参数:AppKey: 应用的key AppSecret: 应用的密钥 PartnerId: 韵达网点分配的…

积水自动监控摄像头

积水自动监控摄像头主要通过安装在关键路段、排水口和易积水区域的摄像头,对降雨和积水情况进行实时监控。这些摄像头配备了先进的图像识别技术,能够自动识别地面是否存在积水,并及时将数据传输到城市管理中心。一旦监测到积水情况,系统会立即发出警报,提醒相关部门迅速采…

清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!

前言 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单。该份教程旨在通过AI技术重构传统科研模式,提升研究效率与智能化水平。DeepSeek访问地址:https://chat.deepseek.com 清华大学推出的 DeepSeek 从入门到精通(104页)免费教程! 清华大学推出第二…