Svelte 最新中文文档教程(16)—— Context(上下文)

前言

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

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

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

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

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

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

Context(上下文)

大多数状态是组件级别的状态,其生命周期与组件相同。然而,也存在应用程序范围或页面范围的状态,这也需要进行相应的处理。

处理这种情况最简单的方法是创建全局状态并直接导入它。

ts 复制代码
/// file: state.svelte.js
export const myGlobalState = $state({
	user: {
		/* ... */
	}
	/* ... */
});
svelte 复制代码
<!--- file: App.svelte --->
<script>
	import { myGlobalState } from './state.svelte.js';
	// ...
</script>

这样做有几个缺点:

  • 只有当您的全局状态仅在客户端使用时,它才能安全地工作 - 例如,当您正在构建一个不在服务端渲染任何组件的单页应用时。如果您的状态最终在服务端被管理和更新,它可能会在 sessions 和(或)用户之间共享,从而导致 bug
  • 这可能给人一种误导性的印象,即某个状态是全局的,而实际上它只应该在你的应用程序的某个特定部分使用

为了解决这些缺点,Svelte 提供了一些 context 原语来缓解这些问题。

设置和获取上下文

要将任意对象与当前组件关联,请使用 setContext

svelte 复制代码
<script>
	import { setContext } from 'svelte';

	setContext('key', value);
</script>

然后,组件的子级(包括插槽内容)可以使用 getContext 访问上下文。

svelte 复制代码
<script>
	import { getContext } from 'svelte';

	const value = getContext('key');
</script>

setContextgetContext 解决了上述问题:

  • 状态不是全局的,而是限定在组件范围内。这样就可以安全地在服务端渲染组件而不会泄露状态
  • 很明显,状态不是全局的,而是限定在特定的组件树中,因此不能在应用的其他部分使用

!NOTE\] `setContext`/`getContext` 必须在组件初始化期间调用。

上下文本身不是响应式的。如果你需要上下文中的响应式值,你可以传递一个 $state 对象到上下文中,其属性 将会 是响应式的。

svelte 复制代码
<!--- file: Parent.svelte --->
<script>
	import { setContext } from 'svelte';

	let value = $state({ count: 0 });
	setContext('counter', value);
</script>

<button onclick={() => value.count++}>增加</button>
svelte 复制代码
<!--- file: Child.svelte --->
<script>
	import { getContext } from 'svelte';

	const value = getContext('counter');
</script>

<p>计数为 {value.count}</p>

要检查给定的 key 是否已在父组件的上下文中设置,可以使用 hasContext

svelte 复制代码
<script>
	import { hasContext } from 'svelte';

	if (hasContext('key')) {
		// 执行某些操作
	}
</script>

您还可以使用 getAllContexts 获取属于最近父组件的整个上下文映射。这在你以编程方式创建组件并想要将现有上下文传递给它时很有用。

svelte 复制代码
<script>
	import { getAllContexts } from 'svelte';

	const contexts = getAllContexts();
</script>

封装上下文交互

上述方法对如何使用它们并没有太多限制。当你的应用规模增长时,将设置和获取上下文封装到函数中并正确地为其添加类型是值得的。

ts 复制代码
// @errors: 2304
import { getContext, setContext } from 'svelte';

let userKey = Symbol('user');

export function setUserContext(user: User) {
	setContext(userKey, user);
}

export function getUserContext(): User {
	return getContext(userKey) as User;
}

Svelte 中文文档

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

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

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

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

相关推荐
一雨方知深秋几秒前
2.fs模块对计算机硬盘进行读写操作(Promise进行封装)
javascript·node.js·promise·v8·cpython
谷歌开发者1 小时前
Web 开发指向标 | Chrome 开发者工具学习资源 (六)
前端·chrome·学习
一晌小贪欢1 小时前
【Html模板】电商运营可视化大屏模板 Excel存储 + 一键导出(已上线-可预览)
前端·数据分析·html·excel·数据看板·电商大屏·大屏看板
发现你走远了1 小时前
连接模拟器网页进行h5的调试(使用Chrome远程调试(推荐)) 保姆级图文
前端·chrome
街尾杂货店&2 小时前
css - 实现三角形 div 容器,用css画一个三角形(提供示例源码)简单粗暴几行代码搞定!
前端·css
顺凡2 小时前
删一个却少俩:Antd Tag 多节点同时消失的原因
前端·javascript·面试
小白路过2 小时前
CSS transform矩阵变换全面解析
前端·css·矩阵
爬山算法2 小时前
Redis(110)Redis的发布订阅机制如何使用?
前端·redis·bootstrap
REDcker3 小时前
前端打包工具 - Rollup 打包工具笔记
前端·笔记
前端大卫3 小时前
动态监听DOM元素高度变化
前端·javascript