bun+svelte+tailwindcss+shadui入门

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 其他

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容