Skip to main content
Svelte 基础
介绍
响应式
属性
逻辑
事件
绑定
类和样式
Actions
过渡动画
Svelte 进阶
高级响应性
复用内容
Motion
高级绑定
高级过渡效果
Context API
特殊元素
<script module>
后续步骤
SvelteKit 基础
介绍
路由
加载数据
请求头和 Cookie
共享模块
表单
API 路由
$app/state
错误和重定向
SvelteKit 进阶
钩子函数
页面选项
链接选项
高级路由
高级加载
环境变量
结论

在之前的练习中,我们了解到状态是深度响应式的 — 例如,如果你改变一个对象的属性,或者向数组中推入元素,它会导致 UI 更新。这是通过创建一个代理来实现的,该代理会拦截读取和写入操作。

有时候,这并不是你想要的。如果你不需要改变个别属性,或者保持引用相等性很重要,那么你可以使用原始状态来代替。

在这个例子中,我们有一个展示 Svelte 不断上涨的股票价格的图表。我们希望在新数据到来时更新图表,我们可以通过将 data 转换为状态来实现...

App
let data = $state(poll());

...但是当数据几毫秒后就会被丢弃时,没有必要使它成为深度响应式的。相反,使用$state.raw

App
let data = $state.raw(poll());

直接修改原始状态不会产生任何效果。通常来说,强烈不建议修改非响应式状态。

在 GitHub 编辑此页面

上一页 下一页
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<script>
	import { scale } from './utils.js';
	import { poll } from './data.js';
 
	let data = poll();
 
	let w = $state(1);
	let h = $state(1);
 
	const min = $derived(Math.min(...data) - 5);
	const max = $derived(Math.max(...data) + 5);
	const x = $derived(scale([0, data.length], [0, w]));
	const y = $derived(scale([min, max], [h, 0]));
 
	const ticks = $derived.by(() => {
		const result = [];
		let n = 10 * Math.ceil(min / 10);
		while (n < max) {
			result.push(n);
			n += 10;
		}
		return result;
	});
 
	$effect(() => {
		const interval = setInterval(() => {
			data = poll();
		}, 200);
 
		return () => {
			clearInterval(interval);
		};
	});
</script>
 
<div class="outer">
	<svg width={w} height={h} bind:clientWidth={w} bind:clientHeight={h}>
		<line y1={h} y2={h} x2={w} />
 
		{#each ticks as tick}
			<g class="tick" transform="translate(0,{y(tick)})">
				<line x2={w} />
				<text x={-5}>{tick}</text>
			</g>
		{/each}
 
		<polyline points={data.map((d, i) => [x(i), y(d)]).join(' ')} />
 
		<text x={10} y={10} font-size={36}>$SVLT</text>
	</svg>
</div>
 
<style>
	.outer {
		width: 100%;
		height: 100%;
		padding: 2em;
		box-sizing: border-box;
	}
 
	svg {
		width: 100%;
		height: 100%;
		overflow: visible;
	}
 
	polyline {
		fill: none;
		stroke: #ff3e00;
		stroke-width: 2;
		stroke-linejoin: round;
		stroke-linecap: round;
	}
 
	line {
		stroke: #aaa;
	}
 
	.tick {
		stroke-dasharray: 2 2;
 
		text {
			text-anchor: end;
			dominant-baseline: middle;
		}
	}
</style>