Truyền dữ liệu qua Props và Emit Events

Tạo bởi Hoàng Vũ, chỉnh sửa cuối lúc 19 tháng 4, 2025

Trong Nuxt (và Vue nói chung), giao tiếp giữa các component là yếu tố quan trọng để tổ chức UI hiệu quả. Bài học này sẽ giúp bạn hiểu cách truyền dữ liệu từ component cha xuống component con thông qua props, cách gửi dữ liệu ngược lại từ con lên cha bằng emit, cũng như cách sử dụng v-model để liên kết hai chiều. Cuối bài học, bạn sẽ thực hành với form input đơn giản có kiểm tra dữ liệu (validation).

Props và Emit Events

1. Truyền dữ liệu từ Cha → Con với props

  • props cho phép component cha truyền dữ liệu vào component con.
  • Con chỉ nhận dữ liệu, không thay đổi trực tiếp props.

Ví dụ:

components/UserCard.vue

<script setup>
defineProps({
  name: String,
  age: Number
})
</script>

<template>
  <div class="border p-4 rounded">
    <p>Tên: {{ name }}</p>
    <p>Tuổi: {{ age }}</p>
  </div>
</template>

Dùng trong trang:

<UserCard name="Nguyễn Văn A" :age="25" />

2. Gửi dữ liệu từ Con → Cha với defineEmits

  • Component con sử dụng defineEmits để phát sự kiện ra ngoài.
  • Cha lắng nghe sự kiện bằng @tenSuKien.

Ví dụ:

components/Counter.vue

<script setup>
const emit = defineEmits(['increment'])

function handleClick() {
  emit('increment')
}
</script>

<template>
  <button @click="handleClick" class="bg-green-500 text-white px-4 py-2 rounded">
    Tăng
  </button>
</template>

Dùng trong trang cha:

<Counter @increment="count++" />
<p>Giá trị: {{ count }}</p>

3. Dùng v-model giữa các componen

  • v-model giúp liên kết hai chiều giữa cha và con.
  • Con cần modelValue (prop) và phát update:modelValue (emit).

Ví dụ:

components/BaseInput.vue

<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])

function updateValue(e) {
  emit('update:modelValue', e.target.value)
}
</script>

<template>
  <input
    :value="modelValue"
    @input="updateValue"
    class="border p-2 rounded w-full"
  />
</template>

Dùng trong trang:

<BaseInput v-model="username" />
<p>Tên bạn là: {{ username }}</p>

4. Thực hành: Form input và kiểm tra dữ liệu đơn giản

Tạo form nhập email và hiển thị lỗi nếu sai định dạng:

components/EmailInput.vue

<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])

const error = ref('')

function validate(e) {
  const value = e.target.value
  emit('update:modelValue', value)
  error.value = !/^\S+@\S+\.\S+$/.test(value) ? 'Email không hợp lệ' : ''
}
</script>

<template>
  <div>
    <input
      :value="modelValue"
      @input="validate"
      class="border p-2 rounded w-full"
      placeholder="Nhập email..."
    />
    <p v-if="error" class="text-red-500 text-sm mt-1">{{ error }}</p>
  </div>
</template>

Dùng trong page:

<EmailInput v-model="email" />

Kết luận

Trong bài này, bạn đã học được cách truyền dữ liệu từ cha đến con bằng props, từ con về cha bằng emit, và liên kết hai chiều bằng v-model. Những kỹ thuật này giúp các component trong dự án Nuxt của bạn giao tiếp linh hoạt và dễ kiểm soát. Việc sử dụng form input để thực hành là bước đầu để xử lý tương tác phức tạp hơn trong ứng dụng thực tế.

Website Logo

Với hơn 10 năm kinh nghiệm lập trình web và từng làm việc với nhiều framework, ngôn ngữ như PHP, JavaScript, React, jQuery, CSS, HTML, CakePHP, Laravel..., tôi hy vọng những kiến thức được chia sẻ tại đây sẽ hữu ích và thiết thực cho các bạn.

Bình luận

Website Logo

Chào, tôi là Vũ. Đây là blog hướng dẫn lập trình của tôi.

Liên hệ công việc qua email dưới đây.

lhvuctu@gmail.com

Chúng Tôi Trên

Bạn đang muốn học về lập trình website?

Bạn cần nâng cao kiến thức chuyên nghiệp hơn để nâng cao cơ hội nghề nghiệp? Liên hệ