Giới thiệu
Vue.js là một framework JavaScript được sử dụng rộng rãi và được đánh giá cao trong cộng đồng phát triển trong những năm qua. Được thiết kế để xây dựng giao diện người dùng, Vue.js có một cộng đồng lớn với nhiều nhà phát triển đóng góp vào sự phát triển của nó. Phiên bản mới nhất, Vue 3, mang đến nhiều tính năng và cải tiến mới đáng chú ý. Trong bài viết này, chúng ta sẽ đánh giá các tính năng mới trong Vue 3.
1. Composition API
Composition API là một tính năng quan trọng trong Vue 3, mang lại sự thay đổi đáng kể so với options API, một phương thức đã được sử dụng trong các phiên bản trước của Vue. Composition API mở ra một cách tiếp cận linh hoạt và có thể mở rộng hơn để tổ chức mã nguồn trong các thành phần Vue.
Với Composition API, bạn có khả năng nhóm các logic có liên quan và tái sử dụng chúng trên nhiều thành phần khác nhau. Điều này mang lại lợi ích lớn khi bạn cần quản lý các thành phần phức tạp, làm cho việc tái sử dụng mã trở nên dễ dàng hơn. Nó giúp tạo ra mã nguồn linh hoạt hơn và giảm sự phức tạp của các thành phần lớn.
Để hiểu rõ hơn về Composition API, bạn có thể tham khảo thêm bài viết “Tìm hiểu Vue Composition API” trên Viblo, nơi mà các khái niệm và ứng dụng của Composition API được giải thích một cách chi tiết và toàn diện.
2. Một vài điểm mới ở component v-model
- V-model arguments: Mặc định,
v-model
trong component sử dụngmodelValue
như một prop vàupdate:modelValue
là một event. Nhưng chúng ta hoàn toàn có thể chỉnh sửa lại name thông qua argument củav-model
:<MyComponent v-model:title="pageTitle" />
Multiple v-model bindings: Bây giờ, chúng ta có thể tạo nhiều v-model
binding trong một đối tượng component. Mỗi v-model
sẽ đồng bộ với một prop khác nhau, mà không cần các tùy chọn bổ sung trong component:
<UserName v-model:first-name="first" v-model:last-name="last" />
<script setup> defineProps({ firstName: String, lastName: String }) defineEmits(['update:firstName', 'update:lastName']) </script> <template> <input type="text" :value="firstName" @input="$emit('update:firstName', $event.target.value)" /> <input type="text" :value="lastName" @input="$emit('update:lastName', $event.target.value)" /> </template>
- Handling
v-model
modifiers: Nếu bạn dùng Vue 2 thì chắc hẳn đã biết một số built-in modifiers củav-model
như là:.lazy
: để đồng bộ hóa sau sau khichange
events<!-- synced after "change" instead of "input" --> <input v-model.lazy="msg" />
.number
: để tự động chỉ định input là kiểu number
<input v-model.number="age" />
- Nếu giá trị không thể được phân tích cú pháp với
parsefloat ()
, thì giá trị ban đầu được sử dụng thay thế. .trim
: để tự động loại bỏ khoảng trắng.
Ngoài một số built-in modifiers nên trên, đôi khi bạn muốn tự tạo ra những modifiers mới như là upperCase, reverseString thì phải làm thế nào? Thật may là ở Vue 3 chúng ta hoàn toàn có thể tự tạo ra modifiers cho riêng mình.
Bây giờ, chúng ta thử tạo một modifier là capitalize
, nó sẽ giúp viết hoa chữ cái đầu tiên của chuỗi.
<MyComponent v-model.capitalize="myText" />
Trong ví dụ dưới đây, chúng ta đã tạo một component có chứa một modelModifiers
mặc định là một object trống:
<script setup> const props = defineProps({ modelValue: String, modelModifiers: { default: () => ({}) } }) defineEmits(['update:modelValue']) console.log(props.modelModifiers) // { capitalize: true } </script> <template> <input type="text" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" /> </template>
Có thể thấy ở ví dụ trên prop modelModifiers
chứa 1 object có key là capitalize
và value là true
. Do chúng ta có viết ở trên v-model.capitalize="myText"
.
Trong code bên dưới, chúng ta sẽ xử lý viết hoa ký tự đầu tiên của chuỗi cho <input />
<script setup> const props = defineProps({ modelValue: String, modelModifiers: { default: () => ({}) } }) const emit = defineEmits(['update:modelValue']) function emitValue(e) { let value = e.target.value if (props.modelModifiers.capitalize) { value = value.charAt(0).toUpperCase() + value.slice(1) } emit('update:modelValue', value) } </script> <template> <input type="text" :value="modelValue" @input="emitValue" /> </template>
3. Teleport
Vue 3 giới thiệu một tính năng mới gọi là teleport, giúp cho việc hiển thị nội dung bên ngoài template của một component dễ dàng hơn. Với teleport, bạn có thể hiển thị nội dung ở một phần khác của DOM mà không cần phải tạo một thành phần mới. Điều này rất hữu ích khi tạo ra các modal, hộp thoại và các phần tử khác cần được hiển thị bên ngoài template của component.
Chúng ta thử tạo một Modal đơn giản như sau:
<div class="outer"> <h3>Vue Teleport Example</h3> <div> <MyModal /> </div> </div>
<script setup> import { ref } from 'vue' const open = ref(false) </script> <template> <button @click="open = true">Open Modal</button> <div v-if="open" class="modal"> <p>Hello from the modal!</p> <button @click="open = false">Close</button> </div> </template> <style scoped> .modal { position: fixed; z-index: 999; top: 20%; left: 50%; width: 300px; margin-left: -150px; } </style>
Như bạn thấy ở component trên gồm có một <button>
có thể kích hoạt việc open modal và một <div>
có class .modal
chứa nội dung của modal và button
để close modal.
Nếu viết modal như trên sẽ có một số vấn đề về CSS:
- Ví dụ, nếu chúng ta dự định làm animate cho
<div class = "outer">
với CSS transform, nó sẽ phá vỡ bố cục của modal! z-index
của modal bị hạn chế bởi elements chứa nó. Nếu có elements khác đè lên<div class="outer">
và cóz-index
cao hơn thì modal của chúng ta sẽ không được hiển thị
Muốn giải quyết vấn đề này chúng ta cần sửa lại <MyModal>
và sử dụng <Teleport>
:
<button @click="open = true">Open Modal</button> <Teleport to="body"> <div v-if="open" class="modal"> <p>Hello from the modal!</p> <button @click="open = false">Close</button> </div> </Teleport>
Giá trị của thuộc tính to
là CSS selector hoặc thẻ html, mục đính là để xác định cho <Teleport>
biết cần “ship” code HTML bên trong đến đâu. Như ví dụ bên trên thì chúng ra sẽ “ship” phần HTML của modal to
thẻ <body>
. Nếu F12 lên chúng ra sẽ thấy rõ điều này:
4. Fragments
Trong Vue 3, một tính năng đặc biệt là sự thêm vào của fragments. Trước đây, các thành phần Vue buộc phải có một phần tử gốc duy nhất. Điều này có nghĩa là nếu bạn muốn trả về nhiều phần tử trong một component, bạn phải bọc chúng trong một phần tử cha. Với fragments, giờ đây bạn có thể trả về nhiều phần tử từ một thành phần mà không cần phải bọc chúng trong một phần tử cha. Điều này giúp làm cho mã nguồn trở nên ngắn gọn và dễ đọc hơn.
Vue 2 Syntax: không hỗ trợ multi-root
<!-- Layout.vue --> <template> <div> <header>...</header> <main>...</main> <footer>...</footer> </div> </template>
Vue 3 Syntax: components bây giờ có thể có multiple root
<!-- Layout.vue --> <template> <header>...</header> <main v-bind="$attrs">...</main> <footer>...</footer> </template>
Tổng kết
Vue 3 mang lại nhiều tính năng và cải tiến mới, trong đó đáng chú ý có Composition API, Fragments, và Teleport. Những thêm vào này không chỉ giúp việc viết mã trở nên dễ dàng hơn, mà còn tạo ra khả năng mở rộng mạnh mẽ, từ đó làm cho Vue trở thành một framework mạnh mẽ hơn để phát triển giao diện người dùng. Cho những người mới bắt đầu với Vue hoặc đang xem xét việc nâng cấp lên Vue 3, những tính năng này đều là điểm đáng chú ý và đáng để khám phá.
(Công cụ editor viết code online: Simple Online Code Editor)
One thought on “Điểm qua một vài tính năng mới trong Vue 3”