字符串、数字等简单变量场景下ref与shallowRef的使用疑问及最佳实践探讨
shallowRef vs ref: Primitive Types, Performance, and Best Practices Hey there, let’s unpack your questions one by one—this is a common point of confusion with Vue’s reactivity system, and it’s great you’re thinking through the tradeoffs!
1. Using shallowRef for strings/numbers: Is there a practical point?
For primitive values like strings or numbers, the difference between ref and shallowRef is barely noticeable in most real-world apps. Here’s the breakdown:
- Primitives don’t have nested properties, so
ref’s deep reactivity logic doesn’t do anything here anyway. Bothref("foo")andshallowRef("foo")only track changes to the.valuereference itself (e.g., when you replace the string entirely withx.value = "bar"). - Performance-wise, any overhead from
ref’s deep check is negligible for primitives—Vue’s reactivity system is optimized to skip deep checks when dealing with non-object values. - Functionally, they work exactly the same: you access/update via
.value, and changes trigger reactivity as expected.
So unless you’re working in an extremely performance-sensitive scenario (like handling thousands of primitive refs at once), using shallowRef instead of ref for primitives doesn’t give you any meaningful benefit.
2. Are string refs "shallow by default"?
In practice, yes—because strings are primitives with no internal properties to monitor. When you create ref("hello"), Vue’s deep reactivity mechanism doesn’t have anything to dig into. It behaves identically to shallowRef("hello") because there’s no "deep" changes to listen for. The deep logic in ref is only relevant when you’re dealing with objects or arrays.
3. Should we default to shallowRef everywhere, only using ref when deep reactivity is needed?
This is a balance between optimization and developer sanity:
- Pros of defaulting to
shallowRef: For large objects/arrays where you only ever replace the entire value (not mutate internal fields),shallowRefavoids unnecessary deep reactivity checks. This can help performance in cases like rendering massive datasets. - Cons of defaulting to
shallowRef: It’s easy to introduce bugs. If you later need to modify a nested property of a value stored inshallowRef, that change won’t trigger reactivity—and debugging this can be a headache. For most apps, the tiny performance gain isn’t worth the risk of accidental non-reactivity.
My take on best practices:
- Primitives: Stick with
ref—it’s the more idiomatic choice in Vue codebases, and there’s no downside.shallowRefworks too, but it’s unnecessary and might confuse other developers reading your code. - Objects/arrays:
- Use
shallowRefif you’re only going to replace the entire object/array (e.g.,user.value = { name: "New Name" }instead ofuser.value.name = "New Name"). - Use
refwhen you need to mutate nested properties or array elements (like pushing to an array or updating an object’s field).
- Use
内容的提问来源于stack exchange,提问作者norr

