refactor(reactivity): adjust APIs

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`.
This commit is contained in:
Evan You
2020-04-15 16:45:20 -04:00
parent 11654a6e50
commit 09b4202a22
11 changed files with 139 additions and 125 deletions

View File

@@ -19,7 +19,7 @@ import {
import { warn } from './warning'
import { Data, ComponentInternalInstance } from './component'
import { isEmitListener } from './componentEmits'
import { InternalObjectSymbol } from './vnode'
import { InternalObjectKey } from './vnode'
export type ComponentPropsOptions<P = Data> =
| ComponentObjectPropsOptions<P>
@@ -104,7 +104,7 @@ export function initProps(
) {
const props: Data = {}
const attrs: Data = {}
def(attrs, InternalObjectSymbol, true)
def(attrs, InternalObjectKey, 1)
setFullProps(instance, rawProps, props, attrs)
const options = instance.type.props
// validation

View File

@@ -4,7 +4,7 @@ import {
VNodeNormalizedChildren,
normalizeVNode,
VNodeChild,
InternalObjectSymbol
InternalObjectKey
} from './vnode'
import {
isArray,
@@ -111,7 +111,7 @@ export const initSlots = (
normalizeVNodeSlots(instance, children)
}
}
def(instance.slots, InternalObjectSymbol, true)
def(instance.slots, InternalObjectKey, 1)
}
export const updateSlots = (

View File

@@ -2,20 +2,24 @@
export const version = __VERSION__
export {
// core
reactive,
ref,
readonly,
// utilities
unref,
shallowRef,
isRef,
toRef,
toRefs,
customRef,
reactive,
isProxy,
isReactive,
readonly,
isReadonly,
// advanced
customRef,
shallowRef,
shallowReactive,
shallowReadonly,
markNonReactive,
markRaw,
toRaw
} from '@vue/reactivity'
export { computed } from './apiComputed'

View File

@@ -17,7 +17,7 @@ import {
ClassComponent
} from './component'
import { RawSlots } from './componentSlots'
import { isReactive, Ref, toRaw } from '@vue/reactivity'
import { isProxy, Ref, toRaw } from '@vue/reactivity'
import { AppContext } from './apiCreateApp'
import {
SuspenseImpl,
@@ -234,7 +234,7 @@ const createVNodeWithArgsTransform = (
)
}
export const InternalObjectSymbol = Symbol()
export const InternalObjectKey = `__vInternal`
export const createVNode = (__DEV__
? createVNodeWithArgsTransform
@@ -262,7 +262,7 @@ function _createVNode(
// class & style normalization.
if (props) {
// for reactive or proxy objects, we need to clone it to enable mutation.
if (isReactive(props) || InternalObjectSymbol in props) {
if (isProxy(props) || InternalObjectKey in props) {
props = extend({}, props)
}
let { class: klass, style } = props
@@ -272,7 +272,7 @@ function _createVNode(
if (isObject(style)) {
// reactive state objects need to be cloned since they are likely to be
// mutated
if (isReactive(style) && !isArray(style)) {
if (isProxy(style) && !isArray(style)) {
style = extend({}, style)
}
props.style = normalizeStyle(style)
@@ -292,16 +292,12 @@ function _createVNode(
? ShapeFlags.FUNCTIONAL_COMPONENT
: 0
if (
__DEV__ &&
shapeFlag & ShapeFlags.STATEFUL_COMPONENT &&
isReactive(type)
) {
if (__DEV__ && shapeFlag & ShapeFlags.STATEFUL_COMPONENT && isProxy(type)) {
type = toRaw(type)
warn(
`Vue received a Component which was made a reactive object. This can ` +
`lead to unnecessary performance overhead, and should be avoided by ` +
`marking the component with \`markNonReactive\` or using \`shallowRef\` ` +
`marking the component with \`markRaw\` or using \`shallowRef\` ` +
`instead of \`ref\`.`,
`\nComponent that was made reactive: `,
type
@@ -454,7 +450,7 @@ export function normalizeChildren(vnode: VNode, children: unknown) {
return
} else {
type = ShapeFlags.SLOTS_CHILDREN
if (!(children as RawSlots)._ && !(InternalObjectSymbol in children!)) {
if (!(children as RawSlots)._ && !(InternalObjectKey in children!)) {
// if slots are not normalized, attach context instance
// (compiled / normalized slots already have context)
;(children as RawSlots)._ctx = currentRenderingInstance