Cùng tìm hiểu về Composition API trong Vue 3

Vue 3.0 đã chính thức ra mắt cách đây không lâu (1 năm có lẻ :)). Là một major version, Vue 3 được giới thiệu với rất nhiều ưu điểm:

  • Cải thiện hiệu năng
  • Bundle nhẹ hơn
  • Tích hợp TypeScript tốt hơn
  • API mới giúp làm việc tốt hơn với dự án quy mô lớn
  • Tạo nền tảng vững chắc cho sự phát triển lâu dài của Vue

Cùng với đó là danh sách Breaking Changes khá dài.

Trong bài viết này mình sẽ tập trung vào Composition API, đây chính là tính năng quan trọng nhất trong phiên bản vue 3 này. Thực ra composition api đã được giới thiệu từ trước phiên bản vue 3 thông qua plugin @vuejs/composition-api, bạn có thể dễ dàng làm quen và tích hợp vào các dự án đang chạy trên vue 2.

Tại sao cần Composition API

Một component điển hình trong Vue có lẽ trông như sau:

Component này có các luồng logic sau:

  1. Gọi API lấy repositories của user được truyền vào từ props, gọi lại API mỗi khi props.user thay đổi
  2. Tìm repositories với queryString
  3. Filter repositories với filters

Chúng ta có thể hình dung ra với những component có logic phức tạp, việc mỗi option này kéo dài vài chục (read: hundreds) dòng là chuyện bình thường.

Việc này dẫn tới các phần logic có liên quan đến nhau, nhưng lại bị chia cắt ra nằm rải rác khắp nơi, khi làm việc chúng ta phải tự hình thành liên kết giữa các phần này trong đầu (mental model).

Và sớm hay muộn (read: almost certainly really soon) chúng ta sẽ quên liên kết này mà thôi, khi đó mỗi khi quay trở lại chúng ta sẽ lại thực hiện lại quy trình hình thành mental model từ đầu.

Việc phân mảnh logic này là một trong những nguyên nhân khiến chúng ta khó làm việc được với những component phức tạp trong Vue.

Bởi vậy sẽ lý tưởng hơn nếu có một cách nào đó chúng ta có thể sắp xếp các phần logic liên quan chỗ nhau vào cùng một chỗ.

Đây chính là vấn đề mà composition được tạo ra để giải quyết.

Composition API cơ bản

Component trong Vue 3 sẽ có thêm một option tên là setup, option này sẽ được chạy trước khi component được tạo ra, sau khi props đã được nhận. Composition API sẽ được viết trong setup.

setup được chạy trước khi component được tạo ra, vì thế bên trong setup chúng ta sẽ không thể truy cập vào bất cứ thành phần nào khác của component ngoại trừ props

setup được viết dưới dạng 1 hàm có input là props (1 input ít sử dụng hơn đó là context),  bất cứ thứ gì trả về tại setup sẽ có thể truy cập được bất cứ đâu trong component (computed, methods, các lifecycle hooks, template…)

setup được thêm vào component trông như thế này:

Bây giờ hãy thử phân tách một luồng logic từ component ban đầu vào setup.

  1. Gọi API lấy repositories của user được truyền vào từ props, gọi lại API mỗi khi props.user thay đổi

Chúng ta khởi tạo danh sách repositories, khai báo một hàm để lấy repositories dựa vào props.user, sau đó trả về 2 đối tượng này.

Chúng ta có thể hình dung biến repositories như một thành phần của data, và getUserRepositories là một phần của methods như ở component thông thường trước đây.

Tuy nhiên một biến thông thường được trả về từ setup sẽ không có tính reactive, các thay đổi của nó sẽ không được nhận ra bởi component, bởi vậy Vue cung cấp hàm ref, biến được khởi tạo với ref sẽ trở nên reactive.

Giá trị của một biến được khởi tạo bằng ref truy cập thông qua value property.

Như vậy phần logic tại datamethods đã được chuyển vào setup, tiếp theo đó là gọi getUserRepositories khi component mounted

Vue tiếp tục cung cấp cho chúng ta một API mới đó là onMounted để sử dụng bên trong setup.

Các lifecycle hook khác đều có thể sử dụng ở setup, Vue cung cấp các lifecycle funciton bằng cách thêm prefix on vào Option Api của chúng.

Chúng ta có thể thấy một pattern dần hình thành: thay vì logic được để rời rạc tại các Option Api, Vue cung cấp cho chúng ta các function và syntax để khai báo/đăng ký/trả về các thành phần reactive tại setup và sử dụng ở phần còn lại của component.

Tiếp chúng ta cần theo dõi sự thay đổi của props.users

Chúng ta import một function mới watch và dùng nó để tạo một watcher phản ứng lại thay đổi của user.

Và để thay đổi của props được ánh xạ vào setup chúng ta cần convert props thành reactive sử dụng toRefs.

Như vậy toàn bộ phần logic trước đây được phân tán ở các Option API bây giờ có thể được tập trung lại tại setup.

Tuy nhiên nếu chỉ như vậy thì khi component trở nên phức tạp, setup cũng sẽ phình siêu to khổng lồ và khi đó chẳng có gì đảm bảo các phần logic của chúng ta sẽ còn dễ theo dõi nữa, Composition API chỉ là mang code từ chỗ này sang chỗ khác mà thôi ???

Composition API không chỉ là di chuyển code qua lại trong component, chúng ta có thể phân tách logic liên quan tới từng nơi riêng biệt (function) và tổ hợp (compose) lại ở setup.

Chúng ta sẽ chi các phần logic riêng biệt ở setup trên:

TLDR;

Composition API là cách thức mới để viết Vue component, bằng cách cung cấp 1 component option mới setup và các fuction cùng pattern để có thể:

  1. Gộp các thành phần logic liên quan đến nhau đang bị phân mảnh ở các Option API về chung một mối.
  2. Tách các phần logic liên quan này thành function riêng biệt đẻ có thể dễ dàng sử dụng lại và quản lý.

Tuy nhiên, chúng ta cần lưu ý rằng, composition api nên được coi là 1 phương án tổ chức code; bạn hoàn toàn có thể lựa chọn sử dụng Composition Api hoặc Options Api tùy từng dự án và yêu cầu đề ra (hoặc là dùng song song cả 2).

Kết

Qua bài viết này bạn có thể thấy rằng Vue 3 thực sự đã được cải tiến hơn nhiều so với Vue 2 và Composition API là một tính năng thú vị và cực kỳ hiệu quả.

Nguồn: Copy có biên tập :)