Skip to main content

Bởi vì chúng ta đang dùng <form>, ứng dụng vẫn hoạt động ngay cả khi người dùng không có JavaScript (điều này xảy ra thường xuyên hơn bạn nghĩ). Thật tuyệt vời, vì nó có nghĩa là ứng dụng của ta rất chắc chắn.

Thường thì người dùng vẫn JavaScript. Khi đó, chúng ta có thể nâng cao dần trải nghiệm, giống như SvelteKit nâng cao dần phần tử <a> bằng cách sử dụng định tuyến phía máy khách.

Import hàm enhance từ $app/forms...

src/routes/+page.svelte
<script>
	import { enhance } from '$app/forms';

	export let data;
	export let form;
</script>

... và thêm chỉ thị use:enhance vào các phần tử

:

src/routes/+page.svelte
<form method="POST" action="?/create" use:enhance>
src/routes/+page.svelte
<form method="POST" action="?/delete" use:enhance>

Vậy là xong! Bây giờ, khi JavaScript được kích hoạt, use:enhance sẽ mô phỏng hành vi tự nhiên của trình duyệt ngoại trừ việc tải lại toàn bộ trang. Nó sẽ:

  • cập nhật prop form
  • hủy hiệu lực của dữ liệu khi phản hồi thành công, làm cho các hàm load chạy lại
  • chuyển đến trang mới khi có phản hồi chuyển hướng
  • hiển thị trang lỗi gần nhất nếu có lỗi xảy ra

Bây giờ chúng ta đang cập nhật trang thay vì tải lại nó, chúng ta có thể làm phức tạp hơn với những thứ như transitions:

src/routes/+page.svelte
<script>
	import { fly, slide } from 'svelte/transition';
	import { enhance } from '$app/forms';

	export let data;
	export let form;
</script>
src/routes/+page.svelte
<li in:fly={{ y: 20 }} out:slide>...</li>

Tiếp theo: Tùy chỉnh use:enhance

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
<script>
	export let data;
	export let form;
</script>
 
<div class="centered">
	<h1>todos</h1>
 
	{#if form?.error}
		<p class="error">{form.error}</p>
	{/if}
 
	<form method="POST" action="?/create">
		<label>
			thêm a todo:
			<input
				name="description"
				value={form?.description ?? ''}
				autocomplete="off"
				required
			/>
		</label>
	</form>
 
	<ul class="todos">
		{#each data.todos as todo (todo.id)}
			<li>
				<form method="POST" action="?/delete">
					<input type="hidden" name="id" value={todo.id} />
					<span>{todo.description}</span>
					<button aria-label="Mark as complete"></button>
				</form>
			</li>
		{/each}
	</ul>
</div>
 
<style>
	.centered {
		max-width: 20em;
		margin: 0 auto;
	}
 
	label {
		width: 100%;
	}
 
	input {
		flex: 1;
	}
 
	span {
		flex: 1;
	}
 
	button {
		border: none;
		background: url(./remove.svg) no-repeat 50% 50%;
		background-size: 1rem 1rem;
		cursor: pointer;
		height: 100%;
		aspect-ratio: 1;
		opacity: 0.5;
		transition: opacity 0.2s;
	}
 
	button:hover {
		opacity: 1;
	}
 
	.saving {
		opacity: 0.5;
	}
</style>
 
initialising