fix(runtime-core): fix globalProperties in check on instance render proxy
This commit is contained in:
parent
4d196366c8
commit
c28a9196b2
@ -1,4 +1,10 @@
|
|||||||
import { h, render, getCurrentInstance, nodeOps } from '@vue/runtime-test'
|
import {
|
||||||
|
h,
|
||||||
|
render,
|
||||||
|
getCurrentInstance,
|
||||||
|
nodeOps,
|
||||||
|
createApp
|
||||||
|
} from '@vue/runtime-test'
|
||||||
import { mockWarn } from '@vue/shared'
|
import { mockWarn } from '@vue/shared'
|
||||||
import { ComponentInternalInstance } from '../src/component'
|
import { ComponentInternalInstance } from '../src/component'
|
||||||
|
|
||||||
@ -137,6 +143,33 @@ describe('component: proxy', () => {
|
|||||||
expect(instance!.sink.foo).toBe(1)
|
expect(instance!.sink.foo).toBe(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('globalProperties', () => {
|
||||||
|
let instance: ComponentInternalInstance
|
||||||
|
let instanceProxy: any
|
||||||
|
const Comp = {
|
||||||
|
setup() {
|
||||||
|
return () => null
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
instance = getCurrentInstance()!
|
||||||
|
instanceProxy = this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const app = createApp(Comp)
|
||||||
|
app.config.globalProperties.foo = 1
|
||||||
|
app.mount(nodeOps.createElement('div'))
|
||||||
|
|
||||||
|
expect(instanceProxy.foo).toBe(1)
|
||||||
|
|
||||||
|
// set should overwrite globalProperties with local
|
||||||
|
instanceProxy.foo = 2
|
||||||
|
expect(instanceProxy.foo).toBe(2)
|
||||||
|
expect(instance!.sink.foo).toBe(2)
|
||||||
|
// should not affect global
|
||||||
|
expect(app.config.globalProperties.foo).toBe(1)
|
||||||
|
})
|
||||||
|
|
||||||
test('has check', () => {
|
test('has check', () => {
|
||||||
let instanceProxy: any
|
let instanceProxy: any
|
||||||
const Comp = {
|
const Comp = {
|
||||||
@ -158,7 +191,11 @@ describe('component: proxy', () => {
|
|||||||
instanceProxy = this
|
instanceProxy = this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
render(h(Comp, { msg: 'hello' }), nodeOps.createElement('div'))
|
|
||||||
|
const app = createApp(Comp, { msg: 'hello' })
|
||||||
|
app.config.globalProperties.global = 1
|
||||||
|
|
||||||
|
app.mount(nodeOps.createElement('div'))
|
||||||
|
|
||||||
// props
|
// props
|
||||||
expect('msg' in instanceProxy).toBe(true)
|
expect('msg' in instanceProxy).toBe(true)
|
||||||
@ -168,6 +205,8 @@ describe('component: proxy', () => {
|
|||||||
expect('bar' in instanceProxy).toBe(true)
|
expect('bar' in instanceProxy).toBe(true)
|
||||||
// public properties
|
// public properties
|
||||||
expect('$el' in instanceProxy).toBe(true)
|
expect('$el' in instanceProxy).toBe(true)
|
||||||
|
// global properties
|
||||||
|
expect('global' in instanceProxy).toBe(true)
|
||||||
|
|
||||||
// non-existent
|
// non-existent
|
||||||
expect('$foobar' in instanceProxy).toBe(false)
|
expect('$foobar' in instanceProxy).toBe(false)
|
||||||
@ -178,6 +217,7 @@ describe('component: proxy', () => {
|
|||||||
expect('baz' in instanceProxy).toBe(true)
|
expect('baz' in instanceProxy).toBe(true)
|
||||||
|
|
||||||
// dev mode ownKeys check for console inspection
|
// dev mode ownKeys check for console inspection
|
||||||
|
// should only expose own keys
|
||||||
expect(Object.keys(instanceProxy)).toMatchObject([
|
expect(Object.keys(instanceProxy)).toMatchObject([
|
||||||
'msg',
|
'msg',
|
||||||
'bar',
|
'bar',
|
||||||
|
@ -159,22 +159,6 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
has(
|
|
||||||
{
|
|
||||||
_: { data, accessCache, renderContext, type, sink }
|
|
||||||
}: ComponentPublicProxyTarget,
|
|
||||||
key: string
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
accessCache![key] !== undefined ||
|
|
||||||
(data !== EMPTY_OBJ && hasOwn(data, key)) ||
|
|
||||||
hasOwn(renderContext, key) ||
|
|
||||||
(type.props && hasOwn(normalizePropsOptions(type.props)[0], key)) ||
|
|
||||||
hasOwn(publicPropertiesMap, key) ||
|
|
||||||
hasOwn(sink, key)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
set(
|
set(
|
||||||
{ _: instance }: ComponentPublicProxyTarget,
|
{ _: instance }: ComponentPublicProxyTarget,
|
||||||
key: string,
|
key: string,
|
||||||
@ -207,6 +191,35 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
},
|
||||||
|
|
||||||
|
has(
|
||||||
|
{
|
||||||
|
_: { data, accessCache, renderContext, type, sink, appContext }
|
||||||
|
}: ComponentPublicProxyTarget,
|
||||||
|
key: string
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
accessCache![key] !== undefined ||
|
||||||
|
(data !== EMPTY_OBJ && hasOwn(data, key)) ||
|
||||||
|
hasOwn(renderContext, key) ||
|
||||||
|
(type.props && hasOwn(normalizePropsOptions(type.props)[0], key)) ||
|
||||||
|
hasOwn(publicPropertiesMap, key) ||
|
||||||
|
hasOwn(sink, key) ||
|
||||||
|
hasOwn(appContext.config.globalProperties, key)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__DEV__ && !__TEST__) {
|
||||||
|
PublicInstanceProxyHandlers.ownKeys = (
|
||||||
|
target: ComponentPublicProxyTarget
|
||||||
|
) => {
|
||||||
|
warn(
|
||||||
|
`Avoid app logic that relies on enumerating keys on a component instance. ` +
|
||||||
|
`The keys will be empty in production mode to avoid performance overhead.`
|
||||||
|
)
|
||||||
|
return Reflect.ownKeys(target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,13 +245,20 @@ export function createDevProxyTarget(instance: ComponentInternalInstance) {
|
|||||||
|
|
||||||
// expose internal instance for proxy handlers
|
// expose internal instance for proxy handlers
|
||||||
Object.defineProperty(target, `_`, {
|
Object.defineProperty(target, `_`, {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: false,
|
||||||
get: () => instance
|
get: () => instance
|
||||||
})
|
})
|
||||||
|
|
||||||
// expose public properties
|
// expose public properties
|
||||||
Object.keys(publicPropertiesMap).forEach(key => {
|
Object.keys(publicPropertiesMap).forEach(key => {
|
||||||
Object.defineProperty(target, key, {
|
Object.defineProperty(target, key, {
|
||||||
get: () => publicPropertiesMap[key](instance)
|
configurable: true,
|
||||||
|
enumerable: false,
|
||||||
|
get: () => publicPropertiesMap[key](instance),
|
||||||
|
// intercepted by the proxy so no need for implementation,
|
||||||
|
// but needed to prevent set errors
|
||||||
|
set: NOOP
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -246,7 +266,10 @@ export function createDevProxyTarget(instance: ComponentInternalInstance) {
|
|||||||
const { globalProperties } = instance.appContext.config
|
const { globalProperties } = instance.appContext.config
|
||||||
Object.keys(globalProperties).forEach(key => {
|
Object.keys(globalProperties).forEach(key => {
|
||||||
Object.defineProperty(target, key, {
|
Object.defineProperty(target, key, {
|
||||||
get: () => globalProperties[key]
|
configurable: true,
|
||||||
|
enumerable: false,
|
||||||
|
get: () => globalProperties[key],
|
||||||
|
set: NOOP
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -264,9 +287,8 @@ export function exposePropsOnDevProxyTarget(
|
|||||||
Object.keys(normalizePropsOptions(propsOptions)[0]).forEach(key => {
|
Object.keys(normalizePropsOptions(propsOptions)[0]).forEach(key => {
|
||||||
Object.defineProperty(proxyTarget, key, {
|
Object.defineProperty(proxyTarget, key, {
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
get: () => instance.props[key],
|
get: () => instance.props[key],
|
||||||
// intercepted by the proxy so no need for implementation,
|
|
||||||
// but needed to prevent set errors
|
|
||||||
set: NOOP
|
set: NOOP
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -280,9 +302,8 @@ export function exposeRenderContextOnDevProxyTarget(
|
|||||||
Object.keys(toRaw(renderContext)).forEach(key => {
|
Object.keys(toRaw(renderContext)).forEach(key => {
|
||||||
Object.defineProperty(proxyTarget, key, {
|
Object.defineProperty(proxyTarget, key, {
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
get: () => renderContext[key],
|
get: () => renderContext[key],
|
||||||
// intercepted by the proxy so no need for implementation,
|
|
||||||
// but needed to prevent set errors
|
|
||||||
set: NOOP
|
set: NOOP
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user