Đăng nhập

BÀI 8: GIAO TIẾP GIỮA COMPONENTS – PROPS & EMIT

  • Hiểu cách cha truyền dữ liệu cho con bằng props
  • Hiểu cách component con gửi sự kiện ngược lại lên cha bằng $emit
  • Làm ví dụ nút Vote để gửi tín hiệu từ con → cha
Hướng giao tiếpCách làm
Cha → ConDùng props
Con → ChaDùng $emit('eventName', data)@eventName="handler"
<!DOCTYPE html>
<html lang="vi">
<head>
  <meta charset="UTF-8">
  <title>Vue Props & Emit</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <style>
    body {
      font-family: Arial;
      display: flex;
      gap: 30px;
      padding: 20px;
    }
    .code {
      width: 50%;
    }
    .output {
      width: 50%;
      border-left: 2px solid #ccc;
      padding-left: 20px;
    }
    .item-box {
      border: 1px solid #ccc;
      padding: 10px;
      margin-bottom: 10px;
      border-radius: 5px;
    }
    button {
      margin-top: 5px;
    }
  </style>
</head>
<body>

  <div class="code">
    <h2>Mã nguồn Vue:</h2>
<pre><code>&lt;div id="app"&gt;
  &lt;h3&gt;Tổng số vote: {{ totalVotes }}&lt;/h3&gt;

  &lt;vote-box
    v-for="(item, index) in items"
    :key="index"
    :title="item"
    @voted="handleVote"
  &gt;&lt;/vote-box&gt;
&lt;/div&gt;

&lt;script&gt;
const { createApp } = Vue;

createApp({
  data() {
    return {
      totalVotes: 0,
      items: ['Bài học Vue', 'React Tutorial', 'Angular Overview']
    };
  },
  methods: {
    handleVote() {
      this.totalVotes++;
    }
  },
  components: {
    'vote-box': {
      props: ['title'],
      template: `
        &lt;div class="item-box"&gt;
          &lt;strong&gt;{{ title }}&lt;/strong&gt;&lt;br&gt;
          &lt;button @click="vote"&gt;Vote +1&lt;/button&gt;
        &lt;/div&gt;
      `,
      methods: {
        vote() {
          this.$emit('voted');
        }
      }
    }
  }
}).mount('#app')
&lt;/script&gt;
</code></pre>
  </div>

  <div class="output">
    <h2>Kết quả hiển thị:</h2>
    <div id="app"></div>
  </div>

  <script>
    const { createApp } = Vue;

    createApp({
      data() {
        return {
          totalVotes: 0,
          items: ['Bài học Vue', 'React Tutorial', 'Angular Overview']
        };
      },
      methods: {
        handleVote() {
          this.totalVotes++;
        }
      },
      components: {
        'vote-box': {
          props: ['title'],
          template: `
            <div class="item-box">
              <strong>{{ title }}</strong><br>
              <button @click="vote">Vote +1</button>
            </div>
          `,
          methods: {
            vote() {
              this.$emit('voted');
            }
          }
        }
      }
    }).mount('#app');
  </script>

</body>
</html>
Thành phầnTác dụng
:title="item"Truyền prop title từ cha → con
@voted="handleVote"Lắng nghe sự kiện từ con emit lên
this.$emit('voted')Component con phát sự kiện voted lên cha
  • Cha truyền dữ liệu qua props
  • Con giao tiếp ngược qua emit
  • Rất hữu ích khi tái sử dụng component như: rating, vote, like, alert…
  1. Truyền thêm score từ con → cha khi vote ($emit('voted', score)).
  2. Cho mỗi component vote-box có biến localVotes, tăng lên mỗi khi bấm.
  3. Đổi button thành icon ❤️ (like), khi bấm hiện Đã thích.

Thảo luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Đăng ký nhận tin mới

Nhận bài học, tài nguyên và cơ hội việc làm qua email hàng tuần.

Chúng tôi cam kết không spam. Bạn có thể hủy bất cứ lúc nào.