Skip to main content
Basic Svelte
Introduction
Reactivity
Props
Logic
Events
Bindings
Classes and styles
Actions
Transitions
Advanced Svelte
Advanced reactivity
Reusing content
Motion
Advanced bindings
Advanced transitions
Context API
Special elements
<script module>
Next steps
Basic SvelteKit
Introduction
Routing
Loading data
Headers and cookies
Shared modules
Forms
API routes
$app/state
Errors and redirects
Advanced SvelteKit
Hooks
Page options
Link options
Advanced routing
Advanced loading
Environment variables
Conclusion

クラスは、データを検証する必要がある場合に特に便利です。この Box クラスの場合、スライダーで許可されている最大値を超えて拡大し続けることはできないはずですが、実際には起ってしまっています。

これを修正するには、widthheightgettersetter (別名 accessors) に置き換えます。まず、これらを プライベート プロパティ に変換します。

App
class Box {
	#width = $state(0);
	#height = $state(0);
	area = $derived(this.#width * this.#height);

	constructor(width, height) {
		this.#width = width;
		this.#height = height;
	}

	// ...
}

次に、いくつかのゲッターとセッターを作成します。

App
class Box {
	// ...

	get width() {
		return this.#width;
	}

	get height() {
		return this.#height;
	}

	set width(value) {
		this.#width = value;
	}

	set height(value) {
		this.#height = value;
	}

	embiggen(amount) {
		this.width += amount;
		this.height += amount;
	}
}

最後に、セッターに検証を追加します。

App
set width(value) {
	this.#width = Math.max(0, Math.min(MAX_SIZE, value));
}

set height(value) {
	this.#height = Math.max(0, Math.min(MAX_SIZE, value));
}

ボタンをどれだけ無理やり押しても、範囲入力の bind:valueembiggen メソッドを介して、ボックスのサイズを限度を超えて増やすことはできなくなりました。

Edit this page on 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
<script>
	const MAX_SIZE = 200;
 
	class Box {
		width = $state(0);
		height = $state(0);
		area = $derived(this.width * this.height);
 
		constructor(width, height) {
			this.width = width;
			this.height = height;
		}
 
		embiggen(amount) {
			this.width += amount;
			this.height += amount;
		}
	}
 
	const box = new Box(100, 100);
</script>
 
<label>
	<input type="range" bind:value={box.width} min={0} max={MAX_SIZE} />
	{box.width}
</label>
 
<label>
	<input type="range" bind:value={box.height} min={0} max={MAX_SIZE} />
	{box.height}
</label>
 
<button onclick={() => box.embiggen(10)}>embiggen</button>
 
<hr>
 
<div
	class="box"
	style:width="{box.width}px"
	style:height="{box.height}px"
>
	{box.area}
</div>
 
<style>
	label {
		display: flex;
		align-items: center;
	}
 
	hr {
		margin: 1em 0;
		border: none;
		border-bottom: 1px solid #888;
	}
 
	.box {
		background: radial-gradient(at 25% 25%, hsl(15 100 60), hsl(15 100 50)) ;
		border-radius: 2px;
		filter: drop-shadow(0 0 10px hsl(15 100 50 / 0.3));
		display: flex;
		align-items: center;
		justify-content: center;
		overflow: hidden;
	}
</style>