Skip to content

Commit

Permalink
dx(runtime-core): warn when expose() is misused (vuejs#7221)
Browse files Browse the repository at this point in the history
  • Loading branch information
skirtles-code authored Jan 9, 2023
1 parent 13dc28a commit 4902354
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 2 deletions.
39 changes: 39 additions & 0 deletions packages/runtime-core/__tests__/apiExpose.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,4 +225,43 @@ describe('api: expose', () => {
expect(grandChildRef.value.$parent).toBe(childRef.value)
expect(grandChildRef.value.$parent.$parent).toBe(grandChildRef.value.$root)
})

test('warning for ref', () => {
const Comp = defineComponent({
setup(_, { expose }) {
expose(ref(1))
return () => null
}
})
render(h(Comp), nodeOps.createElement('div'))
expect(
'expose() should be passed a plain object, received ref'
).toHaveBeenWarned()
})

test('warning for array', () => {
const Comp = defineComponent({
setup(_, { expose }) {
expose(['focus'])
return () => null
}
})
render(h(Comp), nodeOps.createElement('div'))
expect(
'expose() should be passed a plain object, received array'
).toHaveBeenWarned()
})

test('warning for function', () => {
const Comp = defineComponent({
setup(_, { expose }) {
expose(() => null)
return () => null
}
})
render(h(Comp), nodeOps.createElement('div'))
expect(
'expose() should be passed a plain object, received function'
).toHaveBeenWarned()
})
})
23 changes: 21 additions & 2 deletions packages/runtime-core/src/component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { VNode, VNodeChild, isVNode } from './vnode'
import {
isRef,
pauseTracking,
resetTracking,
shallowReadonly,
Expand Down Expand Up @@ -47,6 +48,7 @@ import {
} from './componentEmits'
import {
EMPTY_OBJ,
isArray,
isFunction,
NOOP,
isObject,
Expand Down Expand Up @@ -913,8 +915,25 @@ export function createSetupContext(
instance: ComponentInternalInstance
): SetupContext {
const expose: SetupContext['expose'] = exposed => {
if (__DEV__ && instance.exposed) {
warn(`expose() should be called only once per setup().`)
if (__DEV__) {
if (instance.exposed) {
warn(`expose() should be called only once per setup().`)
}
if (exposed != null) {
let exposedType: string = typeof exposed
if (exposedType === 'object') {
if (isArray(exposed)) {
exposedType = 'array'
} else if (isRef(exposed)) {
exposedType = 'ref'
}
}
if (exposedType !== 'object') {
warn(
`expose() should be passed a plain object, received ${exposedType}.`
)
}
}
}
instance.exposed = exposed || {}
}
Expand Down

0 comments on commit 4902354

Please sign in to comment.