Bạn có thực sự hiểu về Slots?

Tram Ho

image.png

Trong quá trình làm việc với Vuejs thì hẳn ai cũng đã từng sử dụng slot rồi, nhưng liệu ngoài chức năng là thêm nội dung html từ component cha vào component con thì nó còn có tác dụng nào nữa

Hãy đi qua các ví dụ và phương pháp dưới đây để biết xem rằng bạn có thật sự hiểu về slot không?

Đóng gói component

Vấn đề

Ví dụ với 1 component dialog đơn giản như này với thư viện là ElementUI

Component này có 1 biến isVisible và các hàm có chức năng đóng mở dialog

Nhưng khi component mở rộng và có nhiều dialog hơn, các biến và hàm nhiều lên

Các hàm đóng mở lặp đi lặp lại, vậy làm thế nào để tối ưu, chúng ta sẽ đi đến phần sau

Giải quyết

Tạo một component là SlotDialog, component này sẽ đặt 1 slot default, và có biến isVisiblevới 2 function dùng để đóng mở dialog

Và khi dùng thì chúng ta có thể lấy được các props được truyền vào bằng 2 cách là v-slot hoặc là slot-scope

Đối với slot default thì chúng ta có thể viết như trên, còn với ví dụ slot có tên là body thì cú pháp sẽ là

Vậy là quá ví dụ trên chúng ta đã thấy là có thể sử dựng nhiều dialog mà không cần phải tạo các biến và hàm giống nhau

Slot lồng nhau

Vấn đề

Component Counter có 1 biến counter sẽ tăng dần theo mỗi giây được đặt trong slot body

Các thẻ HeaderFooter cũng được dặt trong slot tương ứng

Component này sẽ được dùng ở rất nhiều nơi, mỗi nơi lại có 1 yêu cầu khác nhau, là thay đổi nội dung của body hoặc header, footer

Cách làm chúng ta nghĩ đến đầu tiên sẽ là truyền các props điều kiện vào và if else để thay đổi

Và khi đó, mỗi 1 yêu cầu sẽ là 1 prop mới và thêm các if else, cuối cùng nó sẽ trở thành 1 đống rác

Tư duy khi thiết kế 1 component dùng chung cho nhiều nơi đó là làm thế nào vẫn có thể chỉnh sửa và mở rộng được mà vẫn không làm ảnh hưởng đến những phần khác

Component Counter được lồng bên trong component ChildParent

Component Child sẽ gọi component Counter và sẽ để sẵn các thẻ slot để có thể truyền slot từ component Parent

Lưu ý khi truyền slot 2 tầng thế này thì chúng ta sẽ sử dụng thẻ template, vì nếu sử dụng thẻ div thì component Counter sẽ hiểu rằng ta đang truyền slot với nội dung rỗng từ ngoài vào và nó sẽ đè mất phần slot mặc định bên trong slot đấy

Nếu dùng thẻ div, phải thêm điều kiện để chỉ khi nào có slot truyền vào từ Parent thì mới render ra

Giải quyết

Và bây giờ, chúng ta sẽ sử dụng kỹ thuật scoped slots để lấy giá trị counter từ component Counter ra ngoài Parent

Cuỗi cùng chúng ta đã có thể thay đổi được nội dung từ Parent mà vẫn lấy được các giá trị từ bên trong component Counter

Tối ưu

Cách viết của Child component bên trên đã dùng được, nhưng khi có nhiều slot và prop thì chúng ta lại phải viết đi viết lại rất nhiều

Nên chúng ta sẽ dùng vòng for để render ra các thẻ slot

Kết luận

Scoped slot là một phương pháp giúp chúng ta có thể gói gọn các biến và logic trong 1 component, nhằm tránh dư thừa code

Nhưng đúng theo tên gọi của nó, phạm vi của các prop được lấy ra từ slot chỉ có thể hoạt động được trong scope đấy

Vậy nên tùy vào mỗi trường hợp mà chúng ta sẽ cân nhắc có nên sử dụng hay không, nếu được sử dụng đúng cách thì hiệu quả của phương pháp này đem lại là rất tuyệt vời

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo