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:
- Gọi API lấy repositories của user được truyền vào từ
props
, gọi lại API mỗi khiprops.user
thay đổi - Tìm repositories với
queryString
- 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 trongsetup
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
.
- Gọi API lấy repositories của user được truyền vào từ
props
, gọi lại API mỗi khiprops.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 data
và methods
đã đượ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ầnreactive
tạisetup
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ể:
- 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.
- 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 :)