WeakSets and WeakMaps shows degrading performance as the amount of
observed objects increases. Using hidden keys result in better
performance especially when repeatedly creating large amounts of
reactive proxies.
This also makes it possible to more efficiently declare non-reactive
objects in userland.
BREAKING CHANGE: Reactivity APIs adjustments:
- `readonly` is now non-tracking if called on plain objects.
`lock` and `unlock` have been removed. A `readonly` proxy can no
longer be directly mutated. However, it can still wrap an already
reactive object and track changes to the source reactive object.
- `isReactive` now only returns true for proxies created by `reactive`,
or a `readonly` proxy that wraps a `reactive` proxy.
- A new utility `isProxy` is introduced, which returns true for both
reactive or readonly proxies.
- `markNonReactive` has been renamed to `markRaw`.
BREAKING CHANGE: reactive arrays no longer unwraps contained refs
When reactive arrays contain refs, especially a mix of refs and
plain values, Array prototype methods will fail to function
properly - e.g. sort() or reverse() will overwrite the ref's value
instead of moving it (see #737).
Ensuring correct behavior for all possible Array methods while
retaining the ref unwrapping behavior is exceedinly complicated; In
addition, even if Vue handles the built-in methods internally, it
would still break when the user attempts to use a 3rd party utility
functioon (e.g. lodash) on a reactive array containing refs.
After this commit, similar to other collection types like Map and
Set, Arrays will no longer automatically unwrap contained refs.
The usage of mixed refs and plain values in Arrays should be rare in
practice. In cases where this is necessary, the user can create a
computed property that performs the unwrapping.