Svelte 最新中文文档翻译(4)—— 符文(Runes)下
前言
Svelte,一个非常“有趣”、用起来“很爽”的前端框架。从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1:
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 的引用也会更新——当 count 在 App.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-stepper
ondecrement={() => 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
通过文字建立交流本身就是一种缘分,欢迎围观我的“朋友圈”、加入“低调务实优秀中国好青年”前端社群,分享技术,带你成长。
Svelte 最新中文文档翻译(4)—— 符文(Runes)下的更多相关文章
- SQLAlchemy 中文文档翻译计划
SQLAlchemy 中文文档翻译计划已启动. Python 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质.交流群:467338606. 希望大家能够勇敢地去翻译和改进翻译.虽然我 ...
- Laravel 5.3 中文文档翻译完成
经过一个多月的紧张翻译和校对,翻译完成.以下是参与人员: Laravel 5.3 中文文档翻译完成 稿源:七星互联www . qixoo.com 文档地址在此:https://laravel-chin ...
- WindowsServer2012 R2 64位中文标准版(IIS8.5)下手动搭建PHP环境详细图文教程(二)安装IIS8.5
//来源:http://www.imaoye.com/Technology/WindowsServer2012R264IIS85.html 阿里云服务器ECS Windows Server 2012 ...
- 參与 Spring 4 中文文档翻译
參与 Spring 4 中文文档翻译 我们从2014年12月開始翻译Spring 4的框架文档.尽管至今已有一年,可是进度非常慢. 当中一部分原因是由于Spring 文档有1000多页,并且翻译的时候 ...
- Orchard core 中文文档翻译系列
本系列翻译顺序完全参照 官方顺序 原文地址:https://orchardcore.readthedocs.io/en/latest/ Orchard Core 中文文档翻译(一)关于Orchard ...
- cocos2dx c++ 在mac下写的中文凝视,在win32下编译时不通过
今天遇到个奇怪的问题,在mac下写的程序,加的中文凝视,编译没有问题,可是在win32下(使用的时vs2012, win7 64bit 系统)编译就总是报错 最后在中文凝视后 加一个空格,或者 换行, ...
- zabbix 使用问题两个--中文乱码,以及监控ESXi下的虚拟机
1. 中文乱码 最开始中文显现 长方形不显示文字.解决办法: c:\windows\fonts 下面复制 楷体的字体(字体随意看自己喜欢) 文件名一般为: simkai.ttf 2.将simkai.t ...
- Orchard Core 中文文档翻译(一)关于Orchard Core
原文连接:https://www.cnblogs.com/Qbit/p/9746363.html 转载请注明出处 翻译说明:本系列为直译,按照官方的计划现在这个版本(2018年10月5日)已经接近最终 ...
- vs2015安装VAssistX以后,去除中文注释会有红色下划线方法
---恢复内容开始--- 环境:Visual Studio 2015 问题:代码中出现中文后会带下划线,不舒服-----解决办法. 1.安装完Visual Assist X后会在VS2015的菜单栏出 ...
- async-validator 的中文文档翻译
阿里出品的 antd 和 ElementUI 组件库中表单校验默认使用的 async-validator,它在 gitbub 上也获得了 3.8k 的 star,可见这个库十分强大,奈何只有英文文档看 ...
随机推荐
- 【一步步开发AI运动小程序】十五、AI运动识别中,如何判断人体站位的远近?
[云智AI运动识别小程序插件],可以为您的小程序,赋于人体检测识别.运动检测识别.姿态识别检测AI能力.本地原生识别引擎,无需依赖任何后台或第三方服务,有着识别速度快.体验佳.扩展性强.集成快.成本低 ...
- Ocelot集成Consul实现api网关与服务发现
前言 没看dotnet微服务之API网关Ocelot的请先看,这篇文章接上面文章 安装consul #自定义网络,自定义网络可以指定容器IP,这样服务器重启consul集群也可以正常运行. docke ...
- PHP扩展之Yaconf
这个是继鸟哥出品的yaf,yar 之后的又一个好用的工具. Yaconf配置管理工具 具体可以看鸟哥的文档: https://www.laruence.com/2015/06/12/3051.htm ...
- Jenkins篇-安装与使用
Jenkins是一个开源自动化服务器,可以自动执行持续集成和交付软件所涉及的重复技术任务.Jenkins是基于Java的,可以从Ubuntu软件包安装,也可以通过下载和运行其Web应用程序存档(WAR ...
- OS之《CPU调度》
CPU调度层次 高级调度:是作业调度.将外村的作业加载到内存里,分配对应的资源,然后加入就绪队列 低级调度:将就绪队列中的进程调度到CPU执行 中级调度:为了提高内存的利用率和系统的吞吐量,将暂时不能 ...
- codeforces1849 D. Array Painting
题目链接 https://codeforces.com/problemset/problem/1849/D 题意 输入 \(n(1 \leq n \leq 2e5)\) 和长为 \(n\) 的数组 \ ...
- CHDFS 安全便捷的大数据访问体验
一.背景 云 HDFS(Cloud HDFS,CHDFS)是腾讯云提供的支持标准 HDFS 访问协议.卓越性能.分层命名空间的分布式文件系统. CHDFS 主要解决大数据场景下海量数据存储和数据分析, ...
- FineReport其他js记录
1.js修改日期组件 背景色 边框 setTimeout(function () { var color = "#092347"; var fontColor = "wh ...
- 动态 import()
动态 import() https://v8.dev/features/dynamic-import Dynamic import() 引入了一个新的类似函数的功能,相比静态的 import 提供了新 ...
- 【前端】【探究】HTML - input类型为file时如何实现自定义文本以更好的美化
想到英语四级考了两次都没过,我觉得要多使用英文,所以本文使用英文书写. 本文讲述了遇到的问题,解决的思路,并讲述了解决方案,也许对你会有帮助. 目录 Problem description Solut ...