Vue 3: Những tính năng mới thú vị

Chào các bạn, ở trong bài trước Vue 3: Làm quen và sử dụng thử Composition API chúng ta đã tìm hiểu một tính năng mới và vô cùng hữu ích trong Vue 3 đó là Composition API. Như trong bài viết đó mình đã đề cập, Vue 3 còn nhiều những tính năng mới tuyệt vời khác nữa. Trong bài viết hôm nay chúng ta cùng tìm hiểu một vài những tính năng nổi bật trong số đó các bạn nhé.

Teleport

Teleport – dịch chuyển tức thời ư? Mới nhìn thấy quả tên này thôi là đã thấy ghê gớm rồi. Mặc dù tên nghe hay như vậy nhưng chức năng này thì…cũng hay như tên vậy. Để các bạn hiểu rõ hơn, chúng ta cùng đi vào ví dụ này nhé.

Trong khi xây dựng website thì chắc hẳn các bạn đã sử dụng đến modal (modal của Bootstrap chẳng hạn) đúng không. Và khi làm bằng VueJS thì các bạn sẽ phải chia nhỏ ra thành nhiều components để có thể tái sử dụng chúng thay vì viết chung lại với nhau. Như vậy là bạn sẽ có 1 component là modal.vue với 1 button để mở modal lên như sau:

app.component('modal-button', {
  template: `
    <button @click="modalOpen = true">
        Open full screen modal!
    </button>

    <div v-if="modalOpen" class="modal">
      <div>
        I'm a modal! 
        <button @click="modalOpen = false">
          Close
        </button>
      </div>
    </div>
  `,
  data() {
    return {
      modalOpen: false
    }
  }
})

Tuy nhiên có một điều chắc hẳn các bạn đã gặp phải đó là chúng ta sẽ phải đặt component này ở trong một component khác hay ở thẻ div nào đó mà nó sẽ khiến cho cái modal bị lỗi về giao diện. Ví dụ thẻ div cha mà có position: absolute hay fixed chẳng hạn. Lúc này cách tốt nhất là cho modal ra ngoài làm con của thẻ body, tuy nhiên ta không biết phải làm thế nào cho hợp lý đúng không? Và Teleport ra đời.

app.component('modal-button', {
  template: `
    <button @click="modalOpen = true">
        Open full screen modal! (With teleport!)
    </button>

    <teleport to="body">
      <div v-if="modalOpen" class="modal">
        <div>
          I'm a teleported modal! 
          (My parent is "body")
          <button @click="modalOpen = false">
            Close
          </button>
        </div>
      </div>
    </teleport>
  `,
  data() {
    return {
      modalOpen: false
    }
  }
})

Các bạn hãy để ý vào cặp thẻ <teleport to=”body”></teleport>. Vue 3 cho phép ta dịch chuyển các elements con trong cặp thẻ teleport ra một vị trí bất kì bằng thuộc tính to. Như vậy với ví dụ trên, mặc dù các element nằm trong component modal.vue tuy nhiên khi render nó sẽ được Vue đưa ra ngoài body đó các bạn.

Ngoài ra chúng ta cũng có thể sử dụng để dịch chuyển đến các element khác thông qua selector:

<teleport to="#some-id" />
<teleport to=".some-class" />
<teleport to="some-element" />

Nếu các bạn không muốn teleport nữa thì có thể dùng thuộc tính disabled nhé.

<teleport to="#some-id" :disabled="isDisabled"/>

Fragments

Vue 2

Trong Vue 2 có một điểm mình vô cùng không thích đó là bắt buộc chúng ta phải khai báo một root elements để bao ngoài các elements con trong component đúng không. Như ví dụ dưới đây, nếu chúng ta bỏ cặp thẻ <div> bao ngoài đi thì sẽ báo lỗi ngay lập tức:

<!-- Layout.vue -->
<template>
  <div>
    <header>...</header>
    <main>...</main>
    <footer>...</footer>
  </div>
</template>

Vue 3

Trong Vue 3 thì đã bỏ cái cú pháp này đi, chúng ta hoàn toàn có thể làm như sau mà không sợ báo lỗi lầm gì cả. Thật là tuyệt vời!!!

<template>
  <header>...</header>
  <main v-bind="$attrs">...</main>
  <footer>...</footer>
</template>

Suspense

Lại thêm một tính năng mà mình đánh giá là hữu ích nữa. Khi làm việc với mô hình API – Client trong Vue thì việc gọi API từ Vue lên server để lấy dữ liệu là điều chúng ta thực hiện rất nhiều. Vậy thì trong trường hợp API chưa trả về dữ liệu hoặc dữ liệu bị lỗi thì chúng ta thường phải thêm 1 vài điều kiện (như kiểm tra length của mảng) để nó hiển thị một dòng thông báo chẳng hạn. Ví dụ:

<div v-if="items.length > 0"></div>
<div v-if="items.length === 0">Không có dữ liệu</div>

Vue 3 đã hỗ trợ chúng ta với tính năng Suspense:

<template>
  <suspense>
    <template #default>
      <todo-list />
    </template>
    <template #fallback>
      <div>
        Không có dữ liệu
      </div>
    </template>
  </suspense>
</template>

<script>
export default {
  components: {
    TodoList: defineAsyncComponent(() => import('./TodoList.vue'))
  }
}
</script>

Tuy nhiên nó chỉ hỗ trợ nếu bạn sử dụng Async Component thôi. Các bạn có thể tìm hiểu thêm tại: Async Components

Kết luận

Trên đây là một vài tính năng thú vị của Vue 3, nếu bạn muốn tìm hiểu nhiều những điều mới vẻ hơn nữa thì có thể theo dõi tại trang chủ của Vue: https://v3.vuejs.org/guide/migration/introduction.html#notable-new-features

Trả lời

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 *