Skip to content

Commit 016259f

Browse files
chore: merge conflict
2 parents 212ae3c + 2ffe3d5 commit 016259f

File tree

11 files changed

+125
-112
lines changed

11 files changed

+125
-112
lines changed

packages/reactivity/src/baseHandlers.ts

Lines changed: 55 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import {
2626
hasChanged,
2727
isArray,
2828
isIntegerKey,
29-
extend,
3029
makeMap
3130
} from '@vue/shared'
3231
import { isRef } from './ref'
@@ -45,11 +44,6 @@ const builtInSymbols = new Set(
4544
.filter(isSymbol)
4645
)
4746

48-
const get = /*#__PURE__*/ createGetter()
49-
const shallowGet = /*#__PURE__*/ createGetter(false, true)
50-
const readonlyGet = /*#__PURE__*/ createGetter(true)
51-
const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true)
52-
5347
const arrayInstrumentations = /*#__PURE__*/ createArrayInstrumentations()
5448

5549
function createArrayInstrumentations() {
@@ -91,8 +85,15 @@ function hasOwnProperty(this: object, key: string) {
9185
return obj.hasOwnProperty(key)
9286
}
9387

94-
function createGetter(isReadonly = false, shallow = false) {
95-
return function get(target: Target, key: string | symbol, receiver: object) {
88+
class BaseReactiveHandler implements ProxyHandler<Target> {
89+
constructor(
90+
protected readonly _isReadonly = false,
91+
protected readonly _shallow = false
92+
) {}
93+
94+
get(target: Target, key: string | symbol, receiver: object) {
95+
const isReadonly = this._isReadonly,
96+
shallow = this._shallow
9697
if (key === ReactiveFlags.IS_REACTIVE) {
9798
return !isReadonly
9899
} else if (key === ReactiveFlags.IS_READONLY) {
@@ -155,11 +156,12 @@ function createGetter(isReadonly = false, shallow = false) {
155156
}
156157
}
157158

158-
const set = /*#__PURE__*/ createSetter()
159-
const shallowSet = /*#__PURE__*/ createSetter(true)
159+
class MutableReactiveHandler extends BaseReactiveHandler {
160+
constructor(shallow = false) {
161+
super(false, shallow)
162+
}
160163

161-
function createSetter(shallow = false) {
162-
return function set(
164+
set(
163165
target: object,
164166
key: string | symbol,
165167
value: unknown,
@@ -169,7 +171,7 @@ function createSetter(shallow = false) {
169171
if (isReadonly(oldValue) && isRef(oldValue) && !isRef(value)) {
170172
return false
171173
}
172-
if (!shallow) {
174+
if (!this._shallow) {
173175
if (!isShallow(value) && !isReadonly(value)) {
174176
oldValue = toRaw(oldValue)
175177
value = toRaw(value)
@@ -197,51 +199,50 @@ function createSetter(shallow = false) {
197199
}
198200
return result
199201
}
200-
}
201202

202-
function deleteProperty(target: object, key: string | symbol): boolean {
203-
const hadKey = hasOwn(target, key)
204-
const oldValue = (target as any)[key]
205-
const result = Reflect.deleteProperty(target, key)
206-
if (result && hadKey) {
207-
trigger(target, TriggerOpTypes.DELETE, key, undefined, oldValue)
203+
deleteProperty(target: object, key: string | symbol): boolean {
204+
const hadKey = hasOwn(target, key)
205+
const oldValue = (target as any)[key]
206+
const result = Reflect.deleteProperty(target, key)
207+
if (result && hadKey) {
208+
trigger(target, TriggerOpTypes.DELETE, key, undefined, oldValue)
209+
}
210+
return result
208211
}
209-
return result
210-
}
211212

212-
function has(target: object, key: string | symbol): boolean {
213-
const result = Reflect.has(target, key)
214-
if (!isSymbol(key) || !builtInSymbols.has(key)) {
215-
track(target, TrackOpTypes.HAS, key)
213+
has(target: object, key: string | symbol): boolean {
214+
const result = Reflect.has(target, key)
215+
if (!isSymbol(key) || !builtInSymbols.has(key)) {
216+
track(target, TrackOpTypes.HAS, key)
217+
}
218+
return result
219+
}
220+
ownKeys(target: object): (string | symbol)[] {
221+
track(
222+
target,
223+
TrackOpTypes.ITERATE,
224+
isArray(target) ? 'length' : ITERATE_KEY
225+
)
226+
return Reflect.ownKeys(target)
216227
}
217-
return result
218-
}
219-
220-
function ownKeys(target: object): (string | symbol)[] {
221-
track(target, TrackOpTypes.ITERATE, isArray(target) ? 'length' : ITERATE_KEY)
222-
return Reflect.ownKeys(target)
223228
}
224229

225-
export const mutableHandlers: ProxyHandler<object> = {
226-
get,
227-
set,
228-
deleteProperty,
229-
has,
230-
ownKeys
231-
}
230+
class ReadonlyReactiveHandler extends BaseReactiveHandler {
231+
constructor(shallow = false) {
232+
super(true, shallow)
233+
}
232234

233-
export const readonlyHandlers: ProxyHandler<object> = {
234-
get: readonlyGet,
235-
set(target, key) {
235+
set(target: object, key: string | symbol) {
236236
if (__DEV__) {
237237
warn(
238238
`Set operation on key "${String(key)}" failed: target is readonly.`,
239239
target
240240
)
241241
}
242242
return true
243-
},
244-
deleteProperty(target, key) {
243+
}
244+
245+
deleteProperty(target: object, key: string | symbol) {
245246
if (__DEV__) {
246247
warn(
247248
`Delete operation on key "${String(key)}" failed: target is readonly.`,
@@ -252,22 +253,18 @@ export const readonlyHandlers: ProxyHandler<object> = {
252253
}
253254
}
254255

255-
export const shallowReactiveHandlers = /*#__PURE__*/ extend(
256-
{},
257-
mutableHandlers,
258-
{
259-
get: shallowGet,
260-
set: shallowSet
261-
}
256+
export const mutableHandlers: ProxyHandler<object> =
257+
/*#__PURE__*/ new MutableReactiveHandler()
258+
259+
export const readonlyHandlers: ProxyHandler<object> =
260+
/*#__PURE__*/ new ReadonlyReactiveHandler()
261+
262+
export const shallowReactiveHandlers = /*#__PURE__*/ new MutableReactiveHandler(
263+
true
262264
)
263265

264266
// Props handlers are special in the sense that it should not unwrap top-level
265267
// refs (in order to allow refs to be explicitly passed down), but should
266268
// retain the reactivity of the normal readonly object.
267-
export const shallowReadonlyHandlers = /*#__PURE__*/ extend(
268-
{},
269-
readonlyHandlers,
270-
{
271-
get: shallowReadonlyGet
272-
}
273-
)
269+
export const shallowReadonlyHandlers =
270+
/*#__PURE__*/ new ReadonlyReactiveHandler(true)

packages/runtime-core/src/components/BaseTransition.ts

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ import { RendererElement } from '../renderer'
2222

2323
type Hook<T = () => void> = T | T[]
2424

25+
const leaveCbKey = Symbol('_leaveCb')
26+
const enterCbKey = Symbol('_enterCb')
27+
2528
export interface BaseTransitionProps<HostElement = RendererElement> {
2629
mode?: 'in-out' | 'out-in' | 'default'
2730
appear?: boolean
@@ -89,8 +92,8 @@ export interface TransitionElement {
8992
// in persisted mode (e.g. v-show), the same element is toggled, so the
9093
// pending enter/leave callbacks may need to be cancelled if the state is toggled
9194
// before it finishes.
92-
_enterCb?: PendingCallback
93-
_leaveCb?: PendingCallback
95+
[enterCbKey]?: PendingCallback
96+
[leaveCbKey]?: PendingCallback
9497
}
9598

9699
export function useTransitionState(): TransitionState {
@@ -259,9 +262,9 @@ const BaseTransitionImpl: ComponentOptions = {
259262
)
260263
leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild
261264
// early removal callback
262-
el._leaveCb = () => {
265+
el[leaveCbKey] = () => {
263266
earlyRemove()
264-
el._leaveCb = undefined
267+
el[leaveCbKey] = undefined
265268
delete enterHooks.delayedLeave
266269
}
267270
enterHooks.delayedLeave = delayedLeave
@@ -366,18 +369,18 @@ export function resolveTransitionHooks(
366369
}
367370
}
368371
// for same element (v-show)
369-
if (el._leaveCb) {
370-
el._leaveCb(true /* cancelled */)
372+
if (el[leaveCbKey]) {
373+
el[leaveCbKey](true /* cancelled */)
371374
}
372375
// for toggled element with same key (v-if)
373376
const leavingVNode = leavingVNodesCache[key]
374377
if (
375378
leavingVNode &&
376379
isSameVNodeType(vnode, leavingVNode) &&
377-
leavingVNode.el!._leaveCb
380+
(leavingVNode.el as TransitionElement)[leaveCbKey]
378381
) {
379382
// force early removal (not cancelled)
380-
leavingVNode.el!._leaveCb()
383+
;(leavingVNode.el as TransitionElement)[leaveCbKey]!()
381384
}
382385
callHook(hook, [el])
383386
},
@@ -396,7 +399,7 @@ export function resolveTransitionHooks(
396399
}
397400
}
398401
let called = false
399-
const done = (el._enterCb = (cancelled?) => {
402+
const done = (el[enterCbKey] = (cancelled?) => {
400403
if (called) return
401404
called = true
402405
if (cancelled) {
@@ -407,7 +410,7 @@ export function resolveTransitionHooks(
407410
if (hooks.delayedLeave) {
408411
hooks.delayedLeave()
409412
}
410-
el._enterCb = undefined
413+
el[enterCbKey] = undefined
411414
})
412415
if (hook) {
413416
callAsyncHook(hook, [el, done])
@@ -418,15 +421,15 @@ export function resolveTransitionHooks(
418421

419422
leave(el, remove) {
420423
const key = String(vnode.key)
421-
if (el._enterCb) {
422-
el._enterCb(true /* cancelled */)
424+
if (el[enterCbKey]) {
425+
el[enterCbKey](true /* cancelled */)
423426
}
424427
if (state.isUnmounting) {
425428
return remove()
426429
}
427430
callHook(onBeforeLeave, [el])
428431
let called = false
429-
const done = (el._leaveCb = (cancelled?) => {
432+
const done = (el[leaveCbKey] = (cancelled?) => {
430433
if (called) return
431434
called = true
432435
remove()
@@ -435,7 +438,7 @@ export function resolveTransitionHooks(
435438
} else {
436439
callHook(onAfterLeave, [el])
437440
}
438-
el._leaveCb = undefined
441+
el[leaveCbKey] = undefined
439442
if (leavingVNodesCache[key] === vnode) {
440443
delete leavingVNodesCache[key]
441444
}

packages/runtime-dom/__tests__/patchClass.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { patchProp } from '../src/patchProp'
2-
import { ElementWithTransition } from '../src/components/Transition'
2+
import { ElementWithTransition, vtcKey } from '../src/components/Transition'
33
import { svgNS } from '../src/nodeOps'
44

55
describe('runtime-dom: class patching', () => {
@@ -13,12 +13,12 @@ describe('runtime-dom: class patching', () => {
1313

1414
test('transition class', () => {
1515
const el = document.createElement('div') as ElementWithTransition
16-
el._vtc = new Set(['bar', 'baz'])
16+
el[vtcKey] = new Set(['bar', 'baz'])
1717
patchProp(el, 'class', null, 'foo')
1818
expect(el.className).toBe('foo bar baz')
1919
patchProp(el, 'class', null, null)
2020
expect(el.className).toBe('bar baz')
21-
delete el._vtc
21+
delete el[vtcKey]
2222
patchProp(el, 'class', null, 'foo')
2323
expect(el.className).toBe('foo')
2424
})

packages/runtime-dom/src/components/Transition.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,14 @@ export interface TransitionProps extends BaseTransitionProps<Element> {
3232
leaveToClass?: string
3333
}
3434

35+
export const vtcKey = Symbol('_vtc')
36+
3537
export interface ElementWithTransition extends HTMLElement {
3638
// _vtc = Vue Transition Classes.
3739
// Store the temporarily-added transition classes on the element
3840
// so that we can avoid overwriting them if the element's class is patched
3941
// during the transition.
40-
_vtc?: Set<string>
42+
[vtcKey]?: Set<string>
4143
}
4244

4345
// DOM Transition is a higher-order-component based on the platform-agnostic
@@ -295,18 +297,18 @@ function NumberOf(val: unknown): number {
295297
export function addTransitionClass(el: Element, cls: string) {
296298
cls.split(/\s+/).forEach(c => c && el.classList.add(c))
297299
;(
298-
(el as ElementWithTransition)._vtc ||
299-
((el as ElementWithTransition)._vtc = new Set())
300+
(el as ElementWithTransition)[vtcKey] ||
301+
((el as ElementWithTransition)[vtcKey] = new Set())
300302
).add(cls)
301303
}
302304

303305
export function removeTransitionClass(el: Element, cls: string) {
304306
cls.split(/\s+/).forEach(c => c && el.classList.remove(c))
305-
const { _vtc } = el as ElementWithTransition
307+
const _vtc = (el as ElementWithTransition)[vtcKey]
306308
if (_vtc) {
307309
_vtc.delete(cls)
308310
if (!_vtc!.size) {
309-
;(el as ElementWithTransition)._vtc = undefined
311+
;(el as ElementWithTransition)[vtcKey] = undefined
310312
}
311313
}
312314
}

0 commit comments

Comments
 (0)