Ở bài t-call ta gặp khe 0 của QWeb: nội dung con của lời gọi được "đổ" vào chỗ định sẵn của template kia. OWL có một cơ chế mạnh hơn hẳn cho component: slots. Một component con định nghĩa những chỗ trống, và mỗi nơi dùng nó lại nhét nội dung khác nhau vào — kể cả HTML phức tạp, thậm chí component khác. Bài này dựng một "khung thẻ" dùng chung cho ba nội dung, để thấy slots giải quyết bài toán tái sử dụng theo cách khác props.
props truyền dữ liệu, slots truyền cả một khối giao diện
props (đã học ở loạt OWL) truyền giá trị vào con: một chuỗi, một số, một object. Nhưng khi thứ bạn muốn truyền là cả một mảng HTML — một tiêu đề có icon, một bảng nhỏ, vài nút — thì nhồi vào props rất gượng. Slots sinh ra cho việc đó: con chừa sẵn chỗ, cha đặt nội dung vào.
Con định nghĩa chỗ bằng t-slot; cha đặt nội dung bằng cách viết ngay giữa thẻ component:

Hình 1: Ba mảnh. (1) Con KhoiThe khai hai khe: <t t-slot="header"/> (khe đặt tên "header") và <t t-slot="default"/> (khe mặc định). (2) Nơi gọi: nội dung trong <t t-set-slot="header">...</t> chảy vào khe "header"; mọi con trực tiếp còn lại chảy vào khe default. (3) JS phải khai static components = { KhoiThe } để dùng thẻ <KhoiThe/>.
Slot mặc định và slot đặt tên
Có hai kiểu khe:
- Khe mặc định (
default): nhận con trực tiếp của component — thứ bạn viết ngay giữa<KhoiThe>...</KhoiThe>mà không gói trongt-set-slot. - Khe đặt tên (
header,footer...): nhận nội dung gói trong<t t-set-slot="tên">...</t>.
Nhờ vậy một khung có thể có nhiều "vùng" — tiêu đề, thân, chân — mỗi vùng nơi gọi tự quyết định.
Kết quả: ba thẻ, một khung
Mình dùng KhoiThe ba lần trong bảng điều khiển, mỗi lần bơm tiêu đề và thân khác nhau:

Hình 2: Ba thẻ thật, cùng một component KhoiThe. Khung (viền, header nền xám, body) viết một lần; ba nội dung ("📇 Tổng số thẻ / 4", "⭐ Tổng điểm / 385", "🥇 Thẻ hạng Vàng / 1") do ba lời gọi bơm vào slot. Số liệu là thật (orm.searchRead): 4 thẻ, 385 điểm, 1 thẻ Vàng. Đổi kiểu khung? Sửa KhoiThe, cả ba đổi theo — nhưng nội dung từng thẻ vẫn riêng.
Slots so với t-call và props
t-call(QWeb) tái dùng một template tĩnh, dùng chung context, body vào khe0. Slots là bản nâng cấp cho component: nhiều khe đặt tên, và nội dung slot là của cha (không phải context của con).propstruyền dữ liệu; slots truyền giao diện. Một component hay dùng cả hai: props cho cấu hình (title,color), slots cho nội dung tự do.- Slots còn truyền được dữ liệu ngược ra (scoped slot) khi con muốn cho cha một biến để dùng trong nội dung slot — nhưng đó là mức nâng cao, phần lớn nhu cầu chỉ cần slot mặc định + vài slot tên.
Ba ý mang về
- Slots cho phép nơi gọi nhét cả một khối giao diện vào chỗ định sẵn của component con — giải bài toán tái sử dụng khi thứ cần truyền là HTML/nội dung, không phải một giá trị
props. - Con định nghĩa khe bằng
<t t-slot="tên"/>; cha đặt nội dung bằng<t t-set-slot="tên">...</t>(khe đặt tên) hoặc viết trực tiếp giữa thẻ (khedefault). Nhớstatic components = { Con }để dùng thẻ con. - props truyền dữ liệu, slots truyền giao diện — thường dùng cùng nhau. Slots là bản nâng cấp của khe
0(t-call) dành cho component OWL, với nhiều khe đặt tên.
Ta vừa tách một "khung" ra thành component tái dùng. Phần sau đi sâu hơn vào chia nhỏ thành sub-component: khi nào nên tách một component lớn thành nhiều con, cách chúng nói chuyện qua props và callback, và lợi ích cho việc bảo trì.