-
-
Notifications
You must be signed in to change notification settings - Fork 8.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(reactivity): handle objects with custom Symbol.toStringTag #12832
base: main
Are you sure you want to change the base?
Conversation
Co-authored-by: edison <[email protected]>
❌ Deploy Preview for vue-sfc-playground failed. Why did it fail? →
|
❌ Deploy Preview for vue-next-template-explorer failed. Why did it fail? →
|
packages/reactivity/src/reactive.ts
Outdated
let type = targetTypeMap(toRawType(value)) | ||
|
||
// If the raw type mapping fails, we add extra checks: | ||
if (type === TargetType.INVALID) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the changes should be placed here
core/packages/reactivity/src/reactive.ts
Line 54 in c97bb84
return TargetType.INVALID |
rather than in
getTargetType
should also consider
class MyArray extends Array {
get [Symbol.toStringTag]() {
return 'MyArray'
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@edison1105 I moved the extra type checks into targetTypeMap as suggested and added tests for MyArray. Let me know if you have any more thoughts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made minor tweaks, see 853e933
LGTM. Thanks~
Size ReportBundles
Usages
|
@vue/compiler-core
@vue/compiler-sfc
@vue/compiler-dom
@vue/compiler-ssr
@vue/runtime-core
@vue/runtime-dom
@vue/reactivity
@vue/server-renderer
@vue/shared
vue
@vue/compat
commit: |
close #10483
Problem
When an object from a third-party library defines a custom
Symbol.toStringTag
, the result of callingObject.prototype.toString.call()
on that object becomes something like"[object Goat]"
instead of the default"[object Object]"
. Vue’s reactivity system relies on the result of this call (via its internaltoRawType()
helper) to determine whether an object is plain and should be wrapped in a reactive proxy. As a consequence, objects with a custom tag are mistakenly treated as non-reactive, and mutations to them do not trigger reactive updates.Solution
This PR addresses the issue by modifying the internal
getTargetType
function to include an additional check based on the object's prototype. Specifically:isPlainObject
is introduced (or enhanced) to verify whether an object is plain by checking that its prototype is eitherObject.prototype
ornull
.getTargetType
function, if the initial type mapping returnsTargetType.INVALID
(due to a non-standard tag), the function then checks if the object is plain. If it is, the target type is forced toTargetType.COMMON
, ensuring the object is wrapped in a reactive proxy.This change ensures that objects with a custom
Symbol.toStringTag
are still recognized as plain objects and become reactive as expected.