Trong hành trình phát triển với Vue.js, sự ra đời của Composition API đã mang lại một phong cách lập trình mới mẻ và hiệu quả. Tại Cafedev, chúng tôi luôn quan tâm đến những xu hướng và công nghệ mới, và Vuejs không phải là ngoại lệ. Với sự xuất hiện của Composition API, nhiều câu hỏi thường gặp đã nảy sinh. Trong bài viết này, chúng tôi sẽ giải đáp những thắc mắc phổ biến nhất về Vuejs với Composition API, giúp bạn hiểu rõ hơn về cách sử dụng công nghệ này trong dự án của bạn.

Câu hỏi thường gặp về Vuejs với Composition API

tip Hỏi và đáp này giả định bạn đã có kinh nghiệm trước đó với Vue – đặc biệt là kinh nghiệm với Vue 2 khi chủ yếu sử dụng Options API.

1.Composition API là gì?

Composition API là một tập hợp các API cho phép chúng ta viết các thành phần Vue bằng cách sử dụng các hàm nhập vào thay vì khai báo các tùy chọn. Đây là một thuật ngữ tổng quát bao gồm các API sau:
Reactivity API, ví dụ như ref()reactive(), cho phép chúng ta tạo trực tiếp trạng thái phản ứng, trạng thái tính toán và watchers.
Lifecycle Hooks, ví dụ như onMounted()onUnmounted(), cho phép chúng ta kết nối vào vòng đời của thành phần một cách chương trình.
Dependency Injection, tức là provide()inject(), cho phép chúng ta tận dụng hệ thống dependency injection của Vue khi sử dụng các API phản ứng.
Composition API là một tính năng tích hợp sẵn của Vue 3 và Vue 2.7. Đối với các phiên bản Vue 2 cũ hơn, hãy sử dụng @vue/composition-api plugin được duy trì chính thức. Trong Vue 3, nó cũng chủ yếu được sử dụng cùng với <script setup>

<script setup>
import { ref, onMounted } from 'vue'

// reactive state
const count = ref(0)

// functions that mutate state and trigger updates
function increment() {
  count.value++
}

// lifecycle hooks
onMounted(() => {
  console.log(`The initial count is ${count.value}.`)
})
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

Mặc dù phong cách API dựa trên việc hợp thành các hàm, nhưng Composition API KHÔNG phải là lập trình hàm. Composition API dựa trên mô hình phản ứng tinh tế và có thể thay đổi của Vue, trong khi lập trình hàm nhấn mạnh vào tính không thay đổi.

Nếu bạn quan tâm đến việc học cách sử dụng Vue với Composition API, bạn có thể thiết lập ưu tiên API trên toàn trang thành Composition API bằng cách bật chuyển đổi ở đầu thanh bên trái, sau đó đi qua hướng dẫn từ đầu.

2. Tại sao là Composition API?

Ưu điểm chính của Composition API là nó cho phép tái sử dụng logic một cách sạch sẽ và hiệu quả dưới dạng các hàm có thể hợp thành. Nó giải quyết tất cả các nhược điểm của mixins, cơ chế tái sử dụng logic chính cho Options API.

2.1 Tái Sử Dụng Logic Tốt Hơn

Khả năng tái sử dụng logic của Composition API đã tạo ra các dự án cộng đồng ấn tượng như VueUse, một bộ sưu tập ngày càng lớn các tiện ích có thể hợp thành. Nó cũng phục vụ như một cơ chế sạch sẽ cho việc tích hợp dễ dàng các dịch vụ hoặc thư viện của bên thứ ba có trạng thái vào hệ thống phản ứng của Vue, ví dụ như dữ liệu không thay đổi, máy trạng thái và RxJS.

2.2 Tổ Chức Mã Linh Hoạt Hơn

Nhiều người dùng thích việc chúng ta viết mã được tổ chức mặc định với Options API: mọi thứ đều có đúng chỗ của nó dựa trên tùy chọn nó thuộc về. Tuy nhiên, Options API đặt ra những hạn chế nghiêm trọng khi logic của một thành phần duy nhất phát triển vượt quá một ngưỡng phức tạp nhất định. Hạn chế này đặc biệt nổi bật trong các thành phần cần xử lý nhiều vấn đề logic khác nhau, mà chúng tôi đã chứng kiến trực tiếp trong nhiều ứng dụng Vue 2 sản xuất.

Hãy lấy thành phần trình duyệt thư mục từ giao diện đồ họa của Vue CLI làm ví dụ: thành phần này chịu trách nhiệm về các vấn đề logic sau:

  • Theo dõi trạng thái thư mục hiện tại và hiển thị nội dung của nó
  • Xử lý điều hướng thư mục (mở, đóng, làm mới…)
  • Xử lý việc tạo thư mục mới
  • Chuyển đổi chỉ hiển thị các thư mục yêu thích
  • Chuyển đổi chỉ hiển thị các thư mục ẩn
  • Xử lý thay đổi thư mục làm việc hiện tại Phiên bản ban đầu của thành phần này được viết bằng Options API. Nếu chúng ta gán màu cho mỗi dòng mã dựa trên vấn đề logic mà nó đang xử lý, đây là cách nó trông như thế nào.

Lưu ý cách mã xử lý cùng một vấn đề logic được buộc phải chia thành các tùy chọn khác nhau, đặt ở các phần khác nhau của tệp. Trong một thành phần có độ dài hàng trăm dòng, việc hiểu và điều hướng một vấn đề logic duy nhất đòi hỏi phải liên tục cuộn lên và xuống trong tệp, khiến nó trở nên khó khăn hơn nhiều so với điều cần phải làm. Ngoài ra, nếu chúng ta có ý định trích xuất một vấn đề logic thành một tiện ích có thể tái sử dụng, việc tìm và trích xuất các phần mã phù hợp từ các phần khác nhau của tệp đòi hỏi khá nhiều công việc.

Dưới đây là cùng một thành phần, trước và sau khi tái cấu trúc thành Composition API:

Lưu ý rằng mã liên quan đến cùng một vấn đề logic bây giờ có thể được nhóm lại với nhau: chúng ta không cần phải nhảy giữa các khối tùy chọn khác nhau khi làm việc trên một vấn đề logic cụ thể nữa. Hơn nữa, bây giờ chúng ta có thể di chuyển một nhóm mã vào một tệp bên ngoài mà không cần nhiều công sức, vì chúng ta không còn cần phải di chuyển mã xung quanh để trích xuất chúng. Sự giảm ma sát này trong quá trình tái cấu trúc là yếu tố quan trọng đối với tính bảo trì dài hạn trong các cơ sở mã lớn.

2.3 Tính Suy Luận Kiểu Tốt Hơn

Trong những năm gần đây, ngày càng có nhiều nhà phát triển frontend chuyển sang sử dụng TypeScript vì nó giúp chúng ta viết mã mạnh mẽ hơn, tự tin hơn khi thay đổi, và cung cấp trải nghiệm phát triển tuyệt vời với sự hỗ trợ từ các IDE. Tuy nhiên, Options API, được tạo ra ban đầu vào năm 2013, đã được thiết kế mà không có suy luận kiểu trong tâm trí. Chúng tôi đã phải thực hiện một số thao tác phức tạp vô lý để làm cho suy luận kiểu hoạt động với Options API. Ngay cả với tất cả những nỗ lực này, suy luận kiểu cho Options API vẫn có thể gặp vấn đề với mixins và dependency injection.

Điều này đã khiến nhiều nhà phát triển muốn sử dụng Vue với TS dần chuyển hướng về Class API được hỗ trợ bởi vue-class-component. Tuy nhiên, một API dựa trên lớp nặng phụ thuộc nhiều vào các trình trang trí ES, một tính năng ngôn ngữ chỉ là một đề xuất giai đoạn 2 khi Vue 3 được phát triển vào năm 2019. Chúng tôi cảm thấy rằng việc dựa trên một đề xuất không ổn định để xây dựng một API chính thức là quá rủi ro. Kể từ đó, đề xuất decorators đã trải qua một cuộc tổ chức lại hoàn toàn khác và cuối cùng đạt giai đoạn 3 vào năm 2022. Ngoài ra, API dựa trên lớp gặp phải các hạn chế về tái sử dụng logic và tổ chức tương tự như Options API.

Trong khi đó, Composition API sử dụng chủ yếu các biến và hàm thông thường, tự nhiên thân thiện với kiểu dữ liệu. Mã viết bằng Composition API có thể tận hưởng suy luận kiểu đầy đủ với ít cần thiết phải gợi ý kiểu dữ liệu thủ công. Hầu hết thời gian, mã Composition API sẽ trông tương tự trong TypeScript và JavaScript thuần túy. Điều này cũng làm cho người dùng JavaScript thuần túy có thể hưởng lợi từ suy luận kiểu một phần.

2.4 Gói Sản Phẩm Nhỏ Hơn và Ít Công Việc Phụ Trợ Hơn

Mã viết bằng Composition API và <script setup> cũng hiệu quả hơn và thân thiện với việc thu nhỏ hơn so với phiên bản Options API tương đương. Điều này là vì mẫu trong một thành phần <script setup> được biên dịch thành một hàm được nhúng trong cùng phạm vi của mã <script setup>. Khác với việc truy cập thuộc tính từ this, mã mẫu đã được biên dịch có thể truy cập trực tiếp các biến được khai báo bên trong <script setup>, mà không cần một proxy instance ở giữa. Điều này cũng dẫn đến việc thu nhỏ tốt hơn vì tất cả các tên biến có thể được rút gọn một cách an toàn.

3.Mối quan hệ với Options API

3.1 Các Ưu Điểm và Nhược Điểm

Một số người dùng chuyển từ Options API đã thấy mã Composition API của họ ít được tổ chức hơn và kết luận rằng Composition API “tệ hơn” về tổ chức mã. Chúng tôi khuyến nghị người dùng có ý kiến như vậy nên nhìn vào vấn đề đó từ một góc độ khác.

Đúng là Composition API không còn cung cấp “rào cản” hướng dẫn bạn đặt mã của mình vào các “thùng” tương ứng. Nhưng đổi lại, bạn có thể viết mã thành phần như bạn viết mã JavaScript thông thường. Điều này có nghĩa là bạn có thể và nên áp dụng bất kỳ thực hành tổ chức mã tốt nhất nào vào mã Composition API của mình như bạn đã làm khi viết mã JavaScript thông thường. Nếu bạn có thể viết mã JavaScript được tổ chức tốt, bạn cũng nên có thể viết mã Composition API được tổ chức tốt.

Options API cho phép bạn “nghĩ ít hơn” khi viết mã thành phần, đó là lý do tại sao nhiều người dùng yêu thích nó. Tuy nhiên, khi giảm thiểu gánh nặng tinh thần, nó cũng khóa bạn vào mẫu tổ chức mã đã quy định mà không có cửa thoát, điều này có thể làm cho việc tái cấu trúc hoặc cải thiện chất lượng mã trong các dự án quy mô lớn trở nên khó khăn. Trong điều này, Composition API cung cấp khả năng mở rộng lâu dài tốt hơn.

3.2 Liệu Composition API có đáp ứng tất cả các trường hợp sử dụng không?


Có, đặc biệt trong việc xử lý logic có trạng thái. Khi sử dụng Composition API, chỉ có vài tùy chọn có thể vẫn cần thiết: props, emits, name và inheritAttrs.

MẸO: Kể từ phiên bản 3.3, bạn có thể trực tiếp sử dụng defineOptions trong <script setup> để đặt tên thành phần hoặc thuộc tính inheritAttrs.

Nếu bạn dự định sử dụng độc quyền Composition API (cùng với các tùy chọn được liệt kê ở trên), bạn có thể giảm vài kbs khỏi gói sản phẩm của bạn thông qua một cờ biên dịch thời gian thực mà loại bỏ mã liên quan đến Options API khỏi Vue. Lưu ý rằng điều này cũng ảnh hưởng đến các thành phần Vue trong các phụ thuộc của bạn.

3.3 Tôi có thể sử dụng cả hai API trong cùng một thành phần không?

Có, bạn có thể sử dụng Composition API thông qua tùy chọn setup() trong một thành phần Options API.

Tuy nhiên, chúng tôi chỉ khuyến nghị làm điều này nếu bạn có một cơ sở mã hiện có của Options API cần tích hợp với các tính năng mới / thư viện bên ngoài được viết bằng Composition API.

3.4 Options API sẽ bị loại bỏ không?

Không, chúng tôi không có kế hoạch làm như vậy. Options API là một phần không thể thiếu của Vue và là lý do mà nhiều nhà phát triển yêu thích nó. Chúng tôi cũng nhận ra rằng nhiều lợi ích của Composition API chỉ thể hiện trong các dự án quy mô lớn hơn, và Options API vẫn là một lựa chọn vững chắc cho nhiều kịch bản có độ phức tạp từ thấp đến trung bình.

3.5 Mối quan hệ với Class API

Chúng tôi không còn khuyến nghị sử dụng Class API với Vue 3 nữa, vì Composition API cung cấp tích hợp TypeScript tốt cùng với các lợi ích về tái sử dụng logic và tổ chức mã bổ sung.

4. So sánh với React Hooks

Composition API cung cấp cùng mức độ khả năng hợp thành logic như React Hooks, nhưng với một số khác biệt quan trọng.

React Hooks được gọi lặp đi lặp lại mỗi khi một thành phần cập nhật. Điều này tạo ra một số hạn chế có thể làm rối bời ngay cả với các nhà phát triển React kinh nghiệm. Nó cũng dẫn đến các vấn đề tối ưu hóa hiệu suất có thể ảnh hưởng nghiêm trọng đến trải nghiệm phát triển. Dưới đây là một số ví dụ:

  • Hooks nhạy cảm với thứ tự gọi và không thể điều kiện.
  • Biến được khai báo trong một thành phần React có thể được “bắt” bởi một closure của hook và trở thành “cũ” nếu nhà phát triển không truyền đúng mảng phụ thuộc. Điều này dẫn đến các nhà phát triển React phụ thuộc vào các quy tắc ESLint để đảm bảo các phụ thuộc đúng được truyền. Tuy nhiên, quy tắc thường không thông minh đủ và quá tốn kém để đảm bảo tính chính xác, dẫn đến việc vô hiệu hóa không cần thiết và gây đau đầu khi gặp các trường hợp biên.
  • Các tính toán đắt giá đòi hỏi việc sử dụng useMemo, một lần nữa đòi hỏi truyền vào một mảng phụ thuộc đúng đắn.
  • Các xử lý sự kiện được truyền cho các thành phần con gây ra các cập nhật con không cần thiết theo mặc định, và đòi hỏi useCallback rõ ràng như một tối ưu hóa. Điều này gần như luôn cần thiết, và một lần nữa đòi hỏi một mảng phụ thuộc đúng đắn. Bỏ qua điều này dẫn đến việc mặc định kích hoạt việc vẽ lại ứng dụng và có thể gây ra vấn đề hiệu suất mà không nhận ra được.
  • Vấn đề về closure cũ, kết hợp với các tính năng Concurrent, làm cho việc suy luận về khi một đoạn mã hook được thực thi trở nên khó khăn, và làm cho việc làm việc với trạng thái có thể thay đổi mà cần tồn tại qua các lần vẽ lại (qua useRef) cồng kềnh.

Trong so sánh, Vue Composition API:

  • Gọi setup() hoặc mã <script setup> chỉ một lần. Điều này làm cho mã phù hợp tốt hơn với những dùng tích của việc sử dụng JavaScript theo cách tự nhiên vì không có các closure cũ để lo lắng. Các cuộc gọi Composition API cũng không nhạy cảm với thứ tự gọi và có thể có điều kiện.
  • Hệ thống phản ứng của Vue tự động thu thập các phụ thuộc phản ứng được sử dụng trong các tính năng tính toán và watchers, vì vậy không cần phải khai báo phụ thuộc thủ công.
  • Không cần phải lưu trữ các hàm gọi lại một cách thủ công để tránh cập nhật con không cần thiết. Nhìn chung, hệ thống phản ứng tinh tế của Vue đảm bảo các thành phần con chỉ cập nhật khi cần. Việc tối ưu hóa cập nhật con thủ công hiếm khi là một vấn đề đối với các nhà phát triển Vue. Chúng tôi công nhận sự sáng tạo của React Hooks, và đó là một nguồn cảm hứng chính cho Composition API. Tuy nhiên, các vấn đề được đề cập ở trên thực sự tồn tại trong thiết kế của nó và chúng tôi nhận thấy hệ thống phản ứng của Vue cung cấp một cách giải quyết cho chúng.

Chúng tôi hy vọng rằng những câu trả lời trong bài viết này đã giúp bạn hiểu rõ hơn về Vuejs với Composition API và cung cấp những hướng dẫn hữu ích cho dự án của bạn. Đừng ngần ngại ghé thăm trang web của chúng tôi tại Cafedev để cập nhật thêm thông tin và hướng dẫn về các công nghệ mới nhất. Cảm ơn bạn đã đọc và theo dõi. Hẹn gặp lại tại Cafedev!

Các nguồn kiến thức MIỄN PHÍ VÔ GIÁ từ cafedev tại đây

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của CafeDev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!