ref() với một mảng lớn sẽ gọi reactive() bên trong và chuyển đổi đệ quy toàn bộ object con thành Proxy.
Với 20.000 dòng × nhiều field, chi phí tạo proxy và theo dõi dependency là đáng kể ngay cả khi dữ liệu chỉ dùng để hiển thị.
js
const rows = shallowRef([]) // only .value assignment is reactive
rows.value = await fetchRows() // triggers render once, no deep proxy
rows.value.push(newRow) // does NOT trigger
triggerRef(rows) // force the update after in-place mutationshallowRef: chỉ theo dõi thao tác gán.value. Hợp với dữ liệu thay cả khối (kết quả API, snapshot). Muốn mutate tại chỗ rồi vẫn cập nhật thì gọitriggerRef— hoặc đơn giản là gán mảng mới.shallowReactive: chỉ reactive ở tầng thuộc tính gốc, không đi sâu.markRaw: đánh dấu object không bao giờ được reactive — dùng cho instance thư viện bên thứ ba (map, chart, editor), vừa tránh chi phí proxy vừa tránh lỗi khi thư viện so sánh tham chiếu.
Đánh đổi: mất reactivity sâu nên mọi thay đổi phải đi qua gán lại hoặc triggerRef, dễ sinh bug "sửa dữ liệu mà UI không đổi". Chỉ dùng ở đúng chỗ nóng, và thường phải kết hợp virtual scrolling — vì nút thắt cuối cùng là số DOM node, không chỉ là reactivity.