高级响应式:shallowRef 与 triggerRef
使用 shallowRef 提升性能、使用 markRaw 排除响应式处理,以及使用 triggerRef 手动触发更新
高级响应式:shallowRef 与 triggerRef 是 CoddyKit 上的免费 Vue Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Vue Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Vue Academy 课程共包含 4 节课。
超越引用与响应式状态
Vue 的深层响应式很方便,但并不总是您需要的。对于大型对象或外部实例,深层追踪会造成浪费。Vue 提供了 shallowRef、triggerRef 和 markRaw,让您可以进行精细控制。
响应式引用如何进行深层追踪
保存对象的普通 ref 会使整个对象具备深层响应式——任何嵌套属性发生变更都会触发更新。这适合小型状态,但处理大型结构时成本较高。
import { ref } from "vue"
const user = ref({ name: "Ada", prefs: { theme: "dark" } })
user.value.prefs.theme = "light" // triggers update (deep)shallowRef:只有 .value 具有响应式
shallowRef 会追踪 .value 的重新赋值,但不会追踪所持值内部的变更。内部变更不会触发渲染。
import { shallowRef } from "vue"
const state = shallowRef({ count: 0 })
state.value.count++ // does NOT trigger update
state.value = { count: 1 } // DOES trigger (new .value)何时使用 shallowRef
对于会整体替换的大型、近似不可变的数据,或者需要包装外部对象(例如 chart 实例或大型数据集)时,请使用它。在这些情况下,深层追踪只会增加开销,却没有好处。
const chart = shallowRef(null)
// chart.value = new Chart(...) replaces wholesale深层变更问题
有时,您会在 shallowRef 内执行 DO 变更(出于性能考虑),但仍需要在受控时机重新渲染。Vue 无法察觉这次变化,因此界面会变得过时。
const list = shallowRef([1, 2, 3])
list.value.push(4) // mutated, but no update firestriggerRef:强制更新
triggerRef 会在您变更浅层引用的内容后,手动强制重新运行依赖该引用的副作用。您可以批量执行多次变更,然后只触发一次。
import { shallowRef, triggerRef } from "vue"
const list = shallowRef([1, 2, 3])
list.value.push(4)
list.value.push(5)
triggerRef(list) // now the UI updates一种性能模式
这种模式是:将大型结构保存在 shallowRef 中,随意变更它而无需承担每次变更的响应式开销,然后在希望视图反映这批变更时调用一次 triggerRef。
function bulkUpdate(rows) {
for (const r of rows) data.value.push(r) // cheap
triggerRef(data) // one update
}markRaw:完全退出响应式系统
markRaw 会将对象标记为原始对象,使 Vue 永远不会让它变为响应式对象,即使它位于 reactive 或普通 ref 内部也是如此。对于不应被代理的第三方类实例,请使用它。
import { markRaw, reactive } from "vue"
const state = reactive({
map: markRaw(new ThirdPartyMap()),
})
// state.map is the raw instance, never a proxy为什么 markRaw 很重要
将复杂的类实例(映射对象、编辑器、WebSocket 连接)包装在响应式代理中,可能会破坏其内部引用或导致难以察觉的错误。markRaw 会让它们保持原样,同时仍可存在于响应式状态中。
组合使用这些工具
这些工具可以组合使用:让 shallowRef 保存一个 markRaw 实例,就能得到一个可以以响应式方式替换的容器,而其中的内部对象永远不会被 Vue 代理——这非常适合外部集成。
const editor = shallowRef(null)
function init(el) {
editor.value = markRaw(new CodeEditor(el))
}响应式开销与控制权
其中的权衡是:深层响应性使用起来毫不费力,但开销更大;浅层 API 能让您获得控制权和更高性能,但需要您自行触发更新。只有在性能分析表明确有必要时,才应使用它们。
快速检查
检查您对高级响应式功能的理解。
回顾
您学会了高级响应式控制:
shallowRef只会对.value的重新赋值作出响应,不会响应内部变更——适合大型数据或外部数据。triggerRef会在变更浅层引用的内容后手动强制更新(先批量变更,再触发一次)。markRaw会使对象永久退出响应式系统,非常适合第三方类实例。- 这些工具可以带来更高的性能和更多控制权,但代价是需要您自行触发更新。
常见问题解答
「高级响应式:shallowRef 与 triggerRef」课时是免费的吗?
是的 — 「高级响应式:shallowRef 与 triggerRef」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Vue Academy 课程的其余内容,请升级到 CoddyKit PRO。 Vue Academy 课程共包含 4 节课。
「高级响应式:shallowRef 与 triggerRef」这节课中我会学到什么?
使用 shallowRef 提升性能、使用 markRaw 排除响应式处理,以及使用 triggerRef 手动触发更新 你通过在浏览器中直接运行的动手代码来练习 Vue Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Vue Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Vue Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「高级响应式:shallowRef 与 triggerRef」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Vue Academy 课中编写并运行代码吗?
能。每节 Vue Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 高级响应式:shallowRef 与 triggerRef
- 组合式函数工厂与参数化组合式函数
- 在 Vue 中使用 XState 构建状态机
- 使用 effectScope 管理分组副作用