65 phút
Components và Props
Giới thiệu Components
Components cho phép chia nhỏ UI thành các phần tái sử dụng.
Đăng ký Components
Global Components
// main.js
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.component('MyComponent', {
template: '<div>My Global Component</div>'
})
app.mount('#app')
Local Components
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
}
}
</script>
Props
Định nghĩa Props
<!-- ChildComponent.vue -->
<template>
<div class="user-card">
<h3>{{ name }}</h3>
<p>Email: {{ email }}</p>
<p>Tuổi: {{ age }}</p>
<p v-if="isAdmin">Quản trị viên</p>
</div>
</template>
<script>
export default {
props: {
name: {
type: String,
required: true
},
email: {
type: String,
default: 'No email provided'
},
age: {
type: Number,
validator: (value) => value >= 0
},
isAdmin: {
type: Boolean,
default: false
}
}
}
</script>
Truyền Props
<!-- ParentComponent.vue -->
<template>
<div>
<user-card
name="John Doe"
email="john@example.com"
:age="25"
:is-admin="true"
/>
<user-card
name="Jane Smith"
:age="30"
/>
</div>
</template>
Slots
Default Slot
<!-- BaseLayout.vue -->
<template>
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
Sử dụng Slots
<template>
<base-layout>
<template #header>
<h1>Tiêu đề trang</h1>
</template>
<p>Nội dung chính của trang</p>
<template #footer>
<p>Bản quyền 2024</p>
</template>
</base-layout>
</template>
Emits (Custom Events)
Định nghĩa Emits
<!-- TodoItem.vue -->
<template>
<div class="todo-item">
<span :class="{ completed: todo.completed }">
{{ todo.text }}
</span>
<button @click="$emit('toggle', todo.id)">
{{ todo.completed ? 'Hoàn tác' : 'Hoàn thành' }}
</button>
<button @click="$emit('delete', todo.id)">Xóa</button>
</div>
</template>
<script>
export default {
props: {
todo: {
type: Object,
required: true
}
},
emits: ['toggle', 'delete']
}
</script>
Sử dụng Emits
<template>
<div>
<todo-item
v-for="todo in todos"
:key="todo.id"
:todo="todo"
@toggle="toggleTodo"
@delete="removeTodo"
/>
</div>
</template>
Provide/Inject
Provide từ Component cha
<script setup>
import { provide, ref } from 'vue'
const user = ref({
name: 'John Doe',
role: 'admin'
})
const updateUser = (newUser) => {
user.value = { ...user.value, ...newUser }
}
provide('user', {
user,
updateUser
})
</script>
Inject từ Component con
<script setup>
import { inject } from 'vue'
const { user, updateUser } = inject('user')
const changeName = () => {
updateUser({ name: 'Jane Smith' })
}
</script>