dhphuongg / hit-14-vuejs

Study and discuss about VueJS with HIT

Home Page:https://hit-14-vue-js.vercel.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Lession 08: Component In-depth

I. Props

1. Khai báo Props

const props = defineProps({
  count: {
    type: Number, // kiểu hoặc mảng chứa kiểu của prop
    required: false, // true or false
    default: 10, // giá trị mặc định khi không truyền prop
  },
});

2. Cách sử dụng Prop

a) Khi định nghĩa thì đặt tên theo quy tắc camelCase

defineProps({
  greetingMessage: String,
});

Khi truyền prop thì gọi theo quy tắc kebab-case

<MyComponent greeting-message="hello" />

b) Với kiểu string thì có thể binding tĩnh

<BlogPost title="My journey with Vue" />

Các kiểu còn lại truyền vào prop phải dùng v-bind hoặc :

<!-- kiểu number -->
<BlogPost :likes="42" />

<!-- kiểu boolean -->
<BlogPost is-published />
<BlogPost :is-published="false" />

3. One-Way Data Flow

II. Events

1. Emit và lắng nghe sự kiện

  • B1: Định nghĩa và emit sự kiện ở MyComponent.vue:
const emits = defineEmits(['inFocus', 'submit']);
function buttonClick() {
  emit('submit');
}
<button @click="buttonClick">Click me to submit</button>
  • B2: Ở component cha có thể lắng nghe sự kiên mà MyComponent emit lên
<MyComponent
  @in-focus="callbackFocus"
  @submit="callbackSubmit"
/>

2. Đối số của sự kiện

Khi emit sự kiện ở component con, ngoài đối số đầu tiên là tên sự kiện, nếu ta tryền vào 1 hay nhiều đối số nữa thì ở component cha có thể lấy được đối số đó bằng cách sử dụng tham số ở callback lắng nghe

  • MyButton.vue:
<button @click="emits('eventame', 1, 2, 3)">
  Kích để truyền 1, 2, 3 lên component cha
</button>
  • Khi sử dụng MyButton component:
<MyButton
  @event-name="(p1, p2, p3) => {
  console.log(p1, p2, p3);
}"
/>

3. Kết hợp Props, Emiting và Listening Event để tạo Two-way Data Flow

III. Model

Từ Vue 3.4 trở đi, các component hoàn toàn có thể nhanh chóng tạo cho nó 1 hoặc nhiều props Two-way Data Flow, gọi là model

1. Cơ bản

  • MyComponent.vue:
const model = defineModel({
  type: Number,
  required: false,
  default: 100,
});
function update() {
  model.value++;
}
  • Sử dụng:
const count = ref(0);
<MyComponent v-model="count" />

2. Multiple model

  • Khai báo sẽ đặt tên cho model
const usernameModel = defineModel('username', {
  type: String,
  required: false,
  default: '',
});
  • Khi sử dụng sẽ dụng directives v-model:[modelName]
<MyComponent v-model:username="username" />

IV. Slots

1. Basic

  • Template của FancyButton.vue
<button class="fancy-btn">
  <!-- slot outlet -->
  <slot></slot>
</button>
  • Khi sử dụng, những content ở giữa sẽ được thay thế và đặt vào vị trí slot
<FancyButton>
  <!-- slot content -->
  Click me!
</FancyButton>

Vue slot flow

2. Fallback Content

Chúng ta có thể hiển thị 1 giao diện dự phòng khi có slot outlet nhưng không có slot content

<button class="fancy-btn">
  <!-- slot outlet -->
  <slot>
    <!-- fallback content -->
    Fancy button
  </slot>
</button>

3. Đặt tên cho Slots (Sử dụng nhiều Slots)

Nếu có trên 2 slot thì chúng ta phải đặt tên cho các slot

  • BaseLayout.vue
<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>
  • Khi sử dụng:
<BaseLayout>
  <template #header>
    <!-- content for the header slot -->
  </template>
  <!-- content for the default slot -->
  <div>Main content</div>
  <template #footer>
    <!-- content for the header slot -->
  </template>
</BaseLayout>

Những slot content không đặt trong template hoặc được đặt trong <teamplate #default></teamplate> thì sẽ replace vào slot không có name.

4. Scoped Slots

Sử dụng Scoped Slots để có thể truyền dữ liệu từ Slot outlet lên Slot content

<!-- <MyComponent> template -->
<div>
  <!-- scoped slot outlet -->
  <slot
    :text="greetingMessage"
    :count="1"
  ></slot>
</div>
<MyComponent>
  <!-- scoped slot content -->
  <template #default="{ text, count }">
    <div>
      <p>{{ text }}</p>
      <span>{{ count }}</span>
    </div>
  </template>
</MyComponent>

V. Provide/Inject

Giải quyết được vấn đề truyền props qua nhiều tầng, mà các tầng trung gian không cần thiết

1. Provide

Chúng ta dùng provide để cung cấp 1 value thông qua key cho tất cả các component thuộc component mà sử dụng provide

import { provide, ref } from 'vue';
provide(/* key */ 'message', /* value */ 'hello!');
const count = ref(0);
provide('count', count);

2. Inject

Chúng ta sử dụng inject để lấy value thông qua key mà những component chứa component mà sử dụng inject đã provide

import { inject } from 'vue';
const message = inject('message');

About

Study and discuss about VueJS with HIT

https://hit-14-vue-js.vercel.app


Languages

Language:Vue 72.2%Language:JavaScript 15.9%Language:CSS 8.7%Language:HTML 3.2%