บทเรียน Vue

คอมโพเนนต์ไฟล์เดียวของ Vue 3 พร้อม props ที่มีชนิดข้อมูล defineModel การผูกข้อมูลสองทาง และการส่งผ่าน v-bind="$attrs" ต่อไป

สิ่งที่คุณจะสร้าง

ฟอร์มติดต่อขนาดเล็ก — ช่องกรอกที่มีป้ายกำกับ, ปุ่มส่ง, v-model การผูกข้อมูล, พฤติกรรมของแป้นพิมพ์และโปรแกรมอ่านหน้าจอจริง — เริ่มจากแบบไม่ตกแต่งก่อน แล้วค่อยใส่สไตล์ ภายในประมาณ 10 นาที

ก่อนเริ่ม

คุณต้องมี git, Node 22 ขึ้นไป และ pnpm 10 ขึ้นไป โปรเจกต์ Vue 3 ใดก็ได้ — Nuxt, Vite หรือ Vue ล้วน ๆ

ขั้นที่ 1 — รับโค้ด

git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-vue-headless
pnpm install
pnpm test        # vitest + @testing-library/vue
pnpm run storybook   # browse all 571 components

คอมโพเนนต์เป็นไฟล์แบบแบนอยู่ใน components/ — Button.vue, TextInput.vue — แต่ละตัวมีการทดสอบ story และเอกสารอยู่ข้างกัน คัดลอกไฟล์ที่ต้องการ หรือนำรีโพเข้ามา

ขั้นที่ 2 — คอมโพเนนต์แรกของคุณ

<script setup>
import Button from "lily-design-system-vue-headless/components/Button.vue";
</script>

<template>
  <Button @click="save">Save</Button>
</template>

แสดงผล <button class="button" type="button">props ตรงกับเฟรมเวิร์กอื่น: type, disabled, pressed, labelพร้อมการส่งผ่านแอตทริบิวต์สำหรับอย่างอื่นทั้งหมด

ขั้นที่ 3 — ประกอบฟอร์มเล็ก ๆ

<script setup>
import { ref } from "vue";
import Form from ".../components/Form.vue";
import Field from ".../components/Field.vue";
import TextInput from ".../components/TextInput.vue";
import Button from ".../components/Button.vue";

const name = ref("");
</script>

<template>
  <Form @submit="handleSubmit">
    <Field label="Full name" required>
      <TextInput id="name" label="Full name" v-model="name" required />
    </Field>
    <Button type="submit">Save</Button>
  </Form>
</template>

Field รับ label เป็น prop ของตัวเอง แทนที่จะเป็นคอมโพเนนต์ป้ายกำกับที่ซ้อนอยู่ข้างใน — ส่งเพียงครั้งเดียวที่ Fieldและ TextInputที่ตรงกัน label ให้ชื่อที่เข้าถึงได้

ตรวจสอบเมื่อ 2026-08-29: ร่างก่อนหน้านี้ซ้อนคอมโพเนนต์ Label ภายใน Fieldซึ่งแสดงผล ป้ายกำกับ สองอัน (อันหนึ่งว่างเปล่า) เพราะ Field แสดงป้ายกำกับของตัวเองอยู่แล้วจาก label prop — พบจากการคอมไพล์ตัวอย่างโค้ดจริง เส้นทางฟอร์มติดต่อแบบประกอบ เป็นรูปแบบเดียวกัน และผ่านการทดสอบ e2e และ axe จริง

TextInput ใช้ defineModelดังนั้น v-model ธรรมดาจึงใช้งานได้ทันที

ตรวจสอบงานของคุณ: รันแอปแล้วฟอร์มจะดูธรรมดา — ตามที่ตั้งใจ สไตล์ยังรออยู่ข้างหน้า กด Tabโฟกัสจะเลื่อนผ่านทุกตัวควบคุม ป้ายกำกับถูกอ่านออกเสียง และการส่งทำงานได้ พฤติกรรมเสร็จแล้ว ส่วนรูปลักษณ์เป็นของคุณ และเป็นขั้นต่อไป

ขั้นที่ 4 — ใส่สไตล์

ใส่สไตล์ให้ class hook — .button, .text-input, .label, .field — ในสไตล์ชีตของคุณ หรือลิงก์ธีมสำเร็จรูปใน index.html / nuxt.config:

<link rel="stylesheet" href="/themes/nord.css" />

ขั้นที่ 5 — ดูทุกอย่างทำงาน

แอปตัวอย่าง Nuxt คือแคตตาล็อกทั้งหมดที่มีสไตล์และเดโม พร้อม Playwright e2e และเส้นฐาน axe-core:

git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-vue-nuxt-examples
pnpm install && pnpm run dev

ขั้นต่อไป

มีคำถามระหว่างทางไหม? หน้าช่วยเหลือ เต็มไปด้วยคำตอบ — และถ้าขั้นตอนไหนทำให้ชัดเจนกว่านี้ได้ บอกเรา แล้วเรายินดีปรับปรุงบทเรียน