0x00 创建项目
bunx sv create mvp

info
cd mvp
bun install
0x01 配置shadcn-ui
bunx shadcn-svelte@latest init

info2
0x02 添加 shadcn 的 button
bunx shadcn-svelte@latest add button
写一个测试页:
src/routes/+page.svelte
<script lang="ts">
import { Button } from '$lib/components/ui/button';
</script>
<dev class="flex h-screen w-full flex-col items-center justify-center gap-4 bg-slate-50">
<h1 class="text-4xl font-bold tracking-tight text-slate-900">
Bun + sv + Svelte 5
</h1>
<div class="flex gap-2">
<Button onclick={()=> alert('Svelte 5 Runes!')}>Click Me</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="outline">Outline</Button>
</div>
</dev>
启动:
bun run dev
网页效果:

info2
0x02 添加shadcn 的登录页块
bunx shadcn-svelte@latest add login-01
┌ shadcn-svelte v1.1.0
│
◇ Components to install:
│ login-01
│
◇ Ready to install components and dependencies?
│ Yes
│
▲ The following items already exist:
│ button
│
◇ Would you like to overwrite all existing files?
│ Yes, overwrite everything
│
◇ login-01 installed at src/lib/components/login-01
│
◇ button installed at src/lib/components/ui/button
│
◇ card installed at src/lib/components/ui/card
│
◇ input installed at src/lib/components/ui/input
│
◇ field installed at src/lib/components/ui/field
│
◇ label installed at src/lib/components/ui/label
│
◇ separator installed at src/lib/components/ui/separator
│
◆ Successfully installed dependencies
│
└ Success! Components added.
就得到页面:

image.png
0x03 添加业务逻辑
总结下来,基于上一步导入的模版,可以基于这个文件直接修改,添加响应代码和值绑定等操作。
修改后的代码示例:
<script lang="ts">
import { Button } from '$lib/components/ui/button/index.js';
import * as Card from '$lib/components/ui/card/index.js';
import { Input } from '$lib/components/ui/input/index.js';
import {
FieldGroup,
Field,
FieldLabel
} from '$lib/components/ui/field/index.js';
const id = $props.id();
// 1.定义响应式状态
let email = $state('');
let password = $state('');
let isLoading = $state(false);
let errorMessage = $state('');
// 2.登录处理函数
async function handleLogin(e: Event) {
e.preventDefault();
isLoading = true;
errorMessage = '';
try {
await new Promise(resolve => setTimeout(resolve, 2000));
if (email === 'admin@admin.com' && password === '123456') {
alert('登录成功');
} else {
errorMessage = '邮箱或密码错误,请重试';
}
} catch (error) {
console.log(error);
errorMessage = '服务器连接失败,请稍后再试';
} finally {
isLoading = false;
}
}
</script>
<Card.Root class="mx-auto w-full max-w-sm">
<Card.Header>
<Card.Title class="text-2xl">Login</Card.Title>
<Card.Description>Enter your email below to login to your account</Card.Description>
</Card.Header>
<Card.Content>
<form onsubmit={handleLogin}>
<FieldGroup>
<Field>
<FieldLabel for="email-{id}">Email</FieldLabel>
<Input id="email-{id}" bind:value={email} type="email" placeholder="m@example.com" required />
</Field>
<Field>
<div class="flex items-center">
<FieldLabel for="password-{id}">Password</FieldLabel>
</div>
<Input id="password-{id}" bind:value={password} type="password" required />
</Field>
{#if errorMessage}
<p class="text-sm text-destructive font-medium">{errorMessage}</p>
{/if}
<Field>
<Button type="submit" class="w-full">
{#if isLoading}
Loading...
{:else}
Login
{/if}
</Button>
</Field>
</FieldGroup>
</form>
</Card.Content>
</Card.Root>
0x99 其他
- tailwindcss: https://www.runoob.com/tailwindcss/tailwindcss-basic.html
- shadcn block: https://ui.shadcn.com/blocks#blocks