Svelte 最新中文文档翻译(4)—— 符文(Runes)下

news/2025/1/22 13:54:50/文章来源:https://www.cnblogs.com/yayujs/p/18685674

前言

Svelte,一个非常“有趣”、用起来“很爽”的前端框架。从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1

Image

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

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

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

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

欢迎围观我的“朋友圈”、加入“低调务实优秀中国好青年”前端社群,分享技术,带你成长。

$props

组件的输入称为 props,这是 properties 的缩写。你将 props 传递给组件,就像将属性传递给元素一样:

<!--- file: App.svelte --->
<script>import MyComponent from './MyComponent.svelte';
</script><MyComponent adjective="cool" />

另一方面,在 MyComponent.svelte 内部,我们可以使用 $props 符文接收 props...

<!--- file: MyComponent.svelte --->
<script>let props = $props();
</script><p>这个组件是 {props.adjective}</p>

...更常见的是,你会 解构 你的 props:

<!--- file: MyComponent.svelte --->
<script>let +++{ adjective }+++ = $props();
</script><p>这个组件是 {+++adjective+++}</p>

后备值(Fallback values)

解构允许我们声明后备值,如果父组件没有设置给定的 prop,就会使用这些后备值:

let { adjective = 'happy' } = $props();

[!NOTE] 后备值不会变成响应式状态代理(有关更多信息,请参见更新 props)

重命名 props

我们也可以用解构赋值来重命名 props,如果它们是无效标识符,或者是像 super 这样的 JavaScript 关键字,这样做是必要的:

let { super: trouper = '光芒终会照亮我' } = $props();

剩余 props

最后,我们可以使用 剩余属性 来获取,其实就是获取剩下的 props:

let { a, b, c, ...others } = $props();

更新 props

当 prop 本身更新时,组件内部对该 prop 的引用也会更新——当 countApp.svelte 中发生变化时,它在 Child.svelte 内部也会相应改变。但是子组件能暂时覆盖 prop 的值,这对未保存的临时状态很有用(demo):

<!--- file: App.svelte --->
<script>import Child from './Child.svelte';let count = $state(0);
</script><button onclick={() => (count += 1)}>点击次数(父组件):{count}
</button><Child {count} />
<!--- file: Child.svelte --->
<script>let { count } = $props();
</script><button onclick={() => (count += 1)}>点击次数(子组件):{count}
</button>

虽然你可以临时 重新赋值 props,但除非它们是 可绑定 的 props,否则不应 修改 props。

如果 prop 是一个普通对象,修改将没有效果(demo):

<!--- file: App.svelte --->
<script>import Child from './Child.svelte';
</script><Child object={{ count: 0 }} />
<!--- file: Child.svelte --->
<script>let { object } = $props();
</script><button onclick={() => {// 没有效果object.count += 1
}}>点击次数:{object.count}
</button>

如果 prop 是一个响应式状态代理,那么修改它会产生效果,但你会看到一个 ownership_invalid_mutation 警告,因为该组件正在修改不“属于”它的状态(demo):

<!--- file: App.svelte --->
<script>import Child from './Child.svelte';let object = $state({count: 0});
</script><Child {object} />
<!--- file: Child.svelte --->
<script>let { object } = $props();
</script><button onclick={() => {// 会导致下面的 count 更新,// 但会有警告。不要修改// 你不拥有的对象!object.count += 1
}}>点击次数:{object.count}
</button>

未使用 $bindable 声明的 prop 的后备值将保持不变——它不会被转换为响应式状态代理——这意味着对其的修改不会触发更新(demo):

<!--- file: Child.svelte --->
<script>let { object = { count: 0 } } = $props();
</script><button onclick={() => {// 如果使用默认值,是没有效果的object.count += 1
}}>点击次数:{object.count}
</button>

总之:不要修改 props。要么使用回调 props 来传递变化,要么——如果父子组件应该共享同一个对象——使用 $bindable 符文。

类型安全

通过对 props 进行注解,你可以为组件添加类型安全,就像对其他变量声明一样。在 TypeScript 中,它看起来是这样的...

<script lang="ts">let { adjective }: { adjective: string } = $props();
</script>

...而在 JSDoc 中你可以这样做:

<script>/** @type {{ adjective: string }} */let { adjective } = $props();
</script>

当然,你也可以将类型声明与注解分开:

<script lang="ts">interface Props {adjective: string;}let { adjective }: Props = $props();
</script>

建议添加类型,这样可以确保使用你组件的人可以轻松发现他们应该提供哪些 props。

$bindable

通常情况下,props 是单向的,从父组件流向子组件。这使得理解应用中的数据流向变得容易。

在 Svelte 中,组件的 props 可以被绑定,这意味着数据也可以从子组件流向父组件。这不是你应该经常做的事情,但如果谨慎且适度地使用,可以简化你的代码。

这也意味着状态代理可以在子组件中被修改

[!NOTE] 普通的 props 也可以被修改,但强烈不建议这样做 — 如果 Svelte 检测到一个组件正在修改它不"拥有"的状态,会发出警告。

要将一个 prop 标记为可绑定的,我们使用 $bindable 符文:

/// file: FancyInput.svelte
<script>let { value = $bindable(), ...props } = $props();
</script><input bind:value={value} {...props} /><style>input {font-family: 'Comic Sans MS';color: deeppink;}
</style>

现在,使用 <FancyInput> 的组件可以添加 bind: 指令(demo):

/// App.svelte
<script>import FancyInput from './FancyInput.svelte';let message = $state('hello');
</script><FancyInput bind:value={message} />
<p>{message}</p>

父组件不一定非要使用 bind: — 它可以只传递一个普通的 prop。有些父组件不想听取子组件要说的话。

在这种情况下,你可以为没有传递 prop 时指定一个后备值:

/// file: FancyInput.svelte
let { value = $bindable('fallback'), ...props } = $props();

$inspect

[!NOTE] $inspect 仅在开发环境有效。在生产构建中它会变成空操作。

$inspect 符文大致等同于 console.log,不同之处在于当其参数发生变化时它会重新运行。$inspect 会深度跟踪响应式状态,这意味着使用细粒度响应性更新对象或数组内的内容会导致它重新触发(demo):

<script>let count = $state(0);let message = $state('hello');$inspect(count, message); // 当 `count` 或 `message` 改变时会调用 console.log
</script><button onclick={() => count++}>递增</button>
<input bind:value={message} />

$inspect(...).with

$inspect 返回一个 with 属性,你可以用回调函数调用它,该回调函数将代替 console.log 被调用。回调函数的第一个参数是 "init""update";后续参数是传递给 $inspect 的值(demo):

<script>let count = $state(0);$inspect(count).with((type, count) => {if (type === 'update') {debugger; // 或者使用 `console.trace`,或任何你想要的}});
</script><button onclick={() => count++}>递增</button>

一个找到某些更改的来源的便捷方法是将 console.trace 传递给 with

// @errors: 2304
$inspect(stuff).with(console.trace);

$inspect.trace(...)

这个符文在 5.14 版本中添加,会使周围的函数在开发环境中被追踪。每当函数作为 effect 或 derived 的一部分重新运行时,控制台都会打印出哪些响应式状态导致了 effect 触发。

<script>import { doSomeWork } from './elsewhere';$effect(() => {+++$inspect.trace();+++doSomeWork();});
</script>

$inspect.trace 接受一个可选的第一参数,该参数将被用作标签。

$host

当将组件编译为自定义元素时,$host 符文提供了对宿主元素的访问,使您能够(例如)触发自定义事件(demo):

/// file: Stepper.svelte
<svelte:options customElement="my-stepper" /><script>function dispatch(type) {+++$host()+++.dispatchEvent(new CustomEvent(type));}
</script><button onclick={() => dispatch('decrement')}>减少</button>
<button onclick={() => dispatch('increment')}>增加</button>
/// file: App.svelte
<script>import './Stepper.svelte';let count = $state(0);
</script><my-stepperondecrement={() => count -= 1}onincrement={() => count += 1}
></my-stepper><p>计数: {count}</p>

Svelte 中文文档

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

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

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

通过文字建立交流本身就是一种缘分,欢迎围观我的“朋友圈”、加入“低调务实优秀中国好青年”前端社群,分享技术,带你成长。

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

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

相关文章

固定测斜探头 土体位移变化数据支持 助力工程监测 无线传输

固定测斜探头 土体位移变化数据支持 助力工程监测 无线传输FI系列固定测斜探头是一款专为土体内部位移变化监测而设计的高精度测量仪器。无论是深基坑开挖、地铁地基、公路地基、挡土墙、坝体、尾矿库还是山体滑坡等工程项目,我们的测斜探头都能提供准确可靠的数据支持。该测斜…

研发效率低下?试试这些改进方法

最近这段时间,互联网上发生了很多大事:极越汽车突然宣布破产解散;养乐多上海工厂关闭;网传海信大规模裁员;……2024年即将结束,如果给2024年打个标签,有人说是“愈加魔幻”的一年,有人说是“挑战激增”的一年,也有人说是“生存指数飙升”的一年。 根据裁员追踪机构lay…

复现一下最近的湘岚杯的pwn部分

前言 pwn萌新一枚,这次湘岚杯pwn题只出了两道,后面orw写了exp但是一直打不通,后来发现思路错了。宇宙射线这题很新颖,虽然比赛期间没有做出来,但是赛后复现时学到了很多东西,还是很开兴的。题解过程 ret2text签到 解题思路: ​ 这题是pwn题中的签到题,题目描述也很清晰…

Nature Methods|可解释机器学习在计算生物学中的应用与陷阱

在计算生物学和生物信息学领域,机器学习技术正迅速改变着我们对生物系统的研究方式。然而,随着模型复杂度的增加,如何解释这些模型的行为并从中提取生物学意义,成为了一个亟待解决的问题。 最近,卡内基梅隆大学的Jian Ma和Ameet Talwalkar团队在《Nature Methods》杂志上发…

manim边做边学--淡入淡出变换

今天介绍Manim中用于淡入淡出变换的3个动画类:FadeToColor:聚焦于对象颜色的平滑转换,通过渐变增强视觉效果 FadeTransform:实现不同对象之间的渐变替换,让元素转换更加连贯 FadeTransformPieces:突出将对象碎片化并对各部分单独变换,适用于复杂物体的分解重组这三者都在…

抽取网易云音乐热门评论:html+css+python+js 音乐与灵魂的碰撞

抽取网易云音乐热门评论:html+css+python+js 音乐与灵魂的碰撞抽取网易云音乐热门评论:html+css+python+js 音乐与灵魂的碰撞 代码链接不说废话,上代码!!! get.py # get.py import urllib.request import urllib.error import urllib.parse import json# 抓取网易云音乐指…

快手HoME多任务论文

论文链接:HoME: Hierarchy of Multi-Gate Experts for Multi-Task Learning at Kuaishou 背景 论文指出现在的MMOE/PLE模型存在以下几个问题: 1. 专家崩溃:专家的输出分布存在显着差异,并且一些专家使用 ReLU 的零激活率超过 90%,使得门网络很难分配公平的权重来平衡专家…

Linux 笔记

目录Linux 目录结构Linux 目录与 Windows 目录对比Windows 目录结构Linux 目录结构Linux 世界里---一切皆文件Linux 目录结构详解/bin/sbin/home/root/boot/lib/etc/usr/proc, 别动/srv, 别动/sys, 别动/tmp/dev/media/mnt/opt/usr/local/var/selinux常用快捷键案例常用命令开机…

Prometheus+Grafana 监控搭建

Prometheus+Grafana 监控搭建 Prometheus 是使用 Golang 开发的,安装和运行都非常简单,只需直接运行可执行文件即可。个人认为,只要理解了 Prometheus 的架构图,整体概念就会变得非常清晰。 Prometheus 做的挺成熟,使用非常简单,主要是想自己记录一下,方便后续记忆。 1、…

【防火墙】防火墙监控没做好,断网2小时准备提桶跑路

防火墙告警:该业务CPU负荷过多(81>= 80) ,发现吞吐量超过设备性能阈值,导致网络特别卡,客户端体现就是偶尔网络中断。 之前有篇文章是针对华三的防火墙指标数据采集做了介绍说明,可点击这里查看 网络监控:华三防火墙监控 这篇文章了解,在防火墙可观测性领域目前案例分…

nRF21540—低功耗蓝牙,蓝牙mesh、Thread和Zigbee和2.4 GHz私有协议范围扩展射频前端模块

nRF21540是一款射频前端模块(FEM),可用于改善短距离无线产品的传输范围和连接鲁棒性。作为一款辅助性设备,nRF21540是一种“即插即用型”的无线传输范围扩展器,可与nRF52和nRF53系列的高级多协议无线SoC搭配使用,所需的外部器件数量非常少。 nRF21540的+13dB RX增益和低…

Transformer 学习与解读

LLM学习笔记 注意力机制 sequence to sequence (seq2seq)输入N个向量,输出任意可能数量的向量(由机器决定);如果输出N个向量的任务就叫做Sequence Labeling 李沐课程讲义:https://zh-v2.d2l.ai/chapter_attention-mechanisms/self-attention-and-positional-encoding.ht…