fix(runtime-core): fix component proxy props presence check

fix #864
This commit is contained in:
Evan You 2020-03-21 16:25:33 -04:00
parent c3bb3169f4
commit b3890a93e3
3 changed files with 22 additions and 14 deletions

View File

@ -175,4 +175,18 @@ describe('component: proxy', () => {
instanceProxy.baz = 1 instanceProxy.baz = 1
expect('baz' in instanceProxy).toBe(true) expect('baz' in instanceProxy).toBe(true)
}) })
// #864
test('should not warn declared but absent props', () => {
const Comp = {
props: ['test'],
render(this: any) {
return this.test
}
}
render(h(Comp), nodeOps.createElement('div'))
expect(
`was accessed during render but is not defined`
).not.toHaveBeenWarned()
})
}) })

View File

@ -12,7 +12,8 @@ import {
toRawType, toRawType,
PatchFlags, PatchFlags,
makeMap, makeMap,
isReservedProp isReservedProp,
EMPTY_ARR
} from '@vue/shared' } from '@vue/shared'
import { warn } from './warning' import { warn } from './warning'
import { Data, ComponentInternalInstance } from './component' import { Data, ComponentInternalInstance } from './component'
@ -216,11 +217,11 @@ function validatePropName(key: string) {
return false return false
} }
function normalizePropsOptions( export function normalizePropsOptions(
raw: ComponentPropsOptions | void raw: ComponentPropsOptions | void
): NormalizedPropsOptions { ): NormalizedPropsOptions {
if (!raw) { if (!raw) {
return [] as any return EMPTY_ARR as any
} }
if (normalizationMap.has(raw)) { if (normalizationMap.has(raw)) {
return normalizationMap.get(raw)! return normalizationMap.get(raw)!

View File

@ -15,6 +15,7 @@ import {
currentRenderingInstance, currentRenderingInstance,
markAttrsAccessed markAttrsAccessed
} from './componentRenderUtils' } from './componentRenderUtils'
import { normalizePropsOptions } from './componentProps'
// public properties exposed on the proxy, which is used as the render context // public properties exposed on the proxy, which is used as the render context
// in templates (as `this` in the render option) // in templates (as `this` in the render option)
@ -75,15 +76,7 @@ const enum AccessTypes {
export const PublicInstanceProxyHandlers: ProxyHandler<any> = { export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
get(target: ComponentInternalInstance, key: string) { get(target: ComponentInternalInstance, key: string) {
const { const { renderContext, data, propsProxy, accessCache, type, sink } = target
renderContext,
data,
props,
propsProxy,
accessCache,
type,
sink
} = target
// data / props / renderContext // data / props / renderContext
// This getter gets called for every property access on the render context // This getter gets called for every property access on the render context
@ -110,9 +103,9 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
accessCache![key] = AccessTypes.CONTEXT accessCache![key] = AccessTypes.CONTEXT
return renderContext[key] return renderContext[key]
} else if (type.props) { } else if (type.props) {
// only cache other properties when instance has declared (this stable) // only cache other properties when instance has declared (thus stable)
// props // props
if (hasOwn(props, key)) { if (hasOwn(normalizePropsOptions(type.props)[0], key)) {
accessCache![key] = AccessTypes.PROPS accessCache![key] = AccessTypes.PROPS
// return the value from propsProxy for ref unwrapping and readonly // return the value from propsProxy for ref unwrapping and readonly
return propsProxy![key] return propsProxy![key]