Trong bài đăng này, chúng tôi sẽ viết một ứng dụng TODO đơn giản bằng cách sử dụng SvelteKitand Serverless Redis (Upstash).
SvelteKit là một khuôn khổ để xây dựng các ứng dụng web ở mọi quy mô, với trải nghiệm phát triển đẹp mắt và định tuyến dựa trên hệ thống tệp linh hoạt.
Tạo dự án
Chạy lệnh dưới đây:
npm init svelte@next todo-app-with-redis
Dự án đã sẵn sàng. Bây giờ hãy cài đặt các phụ thuộc và chạy:
npm install
npm run dev
Giao diện Người dùng
Chúng tôi tạo một biểu mẫu đơn giản và một danh sách để giữ các mục cần làm. Nó sẽ trống bây giờ, sau này chúng tôi sẽ liên kết nó với cơ sở dữ liệu.
// src/routes/index.svelte
<script lang="ts">
import type {Todo} from "../lib/types";
import TodoItem from "../components/Todo.svelte";
export let todos: Todo[] = [
{
id: '1',
text: 'Create database',
status: true
},
{
id: '2',
text: 'Copy database url',
status: false
}
];
const uncheckedTodos = todos.filter((todo) => !todo.status);
const checkedTodos = todos.filter((todo) => todo.status);
</script>
<main class="container">
<form class="new" action="/" method="post">
<input
type="text"
name="text"
autofocus
aria-label="Add todo"
class="input"
placeholder="What needs to be done?"
/>
</form>
{#if uncheckedTodos.length}
<div class="todos">
{#each uncheckedTodos as todo (todo.id)}
<TodoItem {todo}/>
{/each}
</div>
{/if}
{#if checkedTodos.length}
<div class="todos todos-done">
{#each checkedTodos as todo (todo.id)}
<TodoItem {todo}/>
{/each}
</div>
{/if}
</main>
Đây là thành phần CẦN LÀM của chúng tôi:
// src/components/Todo.svelte
<script lang="ts">
import type {Todo} from "../lib/types";
export let todo: Todo;
</script>
<div class="todo">
<form action="/?_method=PATCH" method="post">
<input type="hidden" name="todo" value={JSON.stringify(todo)}/>
<button
class="checkbox"
aria-label="Mark todo as {todo.status ? 'not done' : 'done'}"
>
{todo.status ? "✓" : ""}
</button>
</form>
<span class="text">{todo.text}</span>
<form action="/?_method=DELETE" method="post">
<input type="hidden" name="id" value={todo.id}/>
<button class="delete" aria-label="Delete todo">✕</button>
</form>
</div>
Bây giờ bạn sẽ thấy:
Chuẩn bị cơ sở dữ liệu
Chúng tôi sẽ giữ dữ liệu của mình trong Upstash Redis Vì vậy, hãy tạo cơ sở dữ liệu Upstash. Chúng tôi sẽ sử dụng máy khách HTTP dựa trên Upstash thân thiện với môi trường Serverless. Hãy cài đặt:
npm install @upstash/redis
Bây giờ, hãy tạo cơ sở dữ liệu Redis của chúng tôi trên Upstash Console. Sao chép / dán UPSTASH_REDIS_REST_URL
và UPSTASH_REDIS_REST_TOKEN
vào tệp .env.
UPSTASH_REDIS_REST_URL=https://global-renewing-gecko-31543.upstash.io
UPSTASH_REDIS_REST_TOKEN=AXs3ACsjfg684jJBFQgN34je7RFJ58wYjg4NjMt=
Chúng tôi cần cài đặt dotenv để sử dụng các biến môi trường.
npm install dotenv
Bây giờ, hãy tạo lib/redis.ts
và tạo một phiên bản Redis mới như bên dưới:
// src/lib/redis.ts
import "dotenv/config";
import { Redis } from "@upstash/redis";
export const databaseName =
process.env.NODE_ENV === "development"
? "redis-with-svelte-kit-dev"
: "redis-with-svelte-kit";
const redis = new Redis({
url: process.env.UPSTASH_REDIS_REST_URL,
token: process.env.UPSTASH_REDIS_REST_TOKEN,
});
export default redis;
Tạo API
Trong thư mục, js/ts
các tệp được sử dụng làm chương trình phụ trợ API. Vì vậy, index.svelte
-> giao diện người dùng, index.ts
-> chương trình phụ trợ.
Hãy tạo index.ts
và thêm các phương thức API bắt buộc.
// src/routes/index.ts
import redis, { databaseName } from "../lib/redis";
import type { RequestHandler } from "@sveltejs/kit";
const redirect = {
status: 303,
headers: {
location: "/",
},
};
export const get: RequestHandler = async () => {
// runs every time the page is loaded
return { body: { todos: [] } };
};
export const post: RequestHandler = async ({ request }) => {
// form: create todo
return redirect;
};
export const patch: RequestHandler = async ({ request }) => {
// form: update todo
return redirect;
};
export const del: RequestHandler = async ({ request }) => {
// form: delete todo
return redirect;
};
POST
Tạo công việc
Hãy triển khai việc tạo mục TODO:
// src/routes/index.ts
export const post: RequestHandler = async ({ request }) => {
const form = await request.formData();
const text = form.get("text");
const id = Date.now().toString();
const todo = JSON.stringify({ text, status: false });
await redis.hset(databaseName, id, todo);
return redirect;
};
GET
Tải công việc
Bây giờ, hãy liệt kê các mục CẦN LÀM:
// src/routes/index.ts
export const get: RequestHandler = async () => {
let todos = [];
const data = await redis.hgetall(databaseName);
if (!data) return { body: { todos } };
// normalize data
todos = Object.keys(data)
.map((key) => ({
id: key,
text: data[key]["text"],
status: data[key]["status"],
}))
// id = timestamp
.sort((a, b) => parseInt(b.id) - parseInt(a.id));
return { body: { todos } };
};
Để giữ cho bài viết đơn giản, tôi đã không thêm
task deletion
vàtaks completion
mã ở đây, nhưng bạn có thể thấy chúng trong github repo.
Bây giờ mọi thứ đã sẵn sàng!
Mã nguồn | Ứng dụng Demo
Tôi đang lên kế hoạch triển khai ứng dụng TODO tương tự với Next.js. Sau đó, tôi sẽ so sánh kinh nghiệm của mình trong các khuôn khổ này.
Hãy theo dõi và theo dõi chúng tôi tại Twitterand Discord.