Skip to content

Commit 4902354

Browse files
dx(runtime-core): warn when expose() is misused (#7221)
1 parent 13dc28a commit 4902354

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

packages/runtime-core/__tests__/apiExpose.spec.ts

+39
Original file line numberDiff line numberDiff line change
@@ -225,4 +225,43 @@ describe('api: expose', () => {
225225
expect(grandChildRef.value.$parent).toBe(childRef.value)
226226
expect(grandChildRef.value.$parent.$parent).toBe(grandChildRef.value.$root)
227227
})
228+
229+
test('warning for ref', () => {
230+
const Comp = defineComponent({
231+
setup(_, { expose }) {
232+
expose(ref(1))
233+
return () => null
234+
}
235+
})
236+
render(h(Comp), nodeOps.createElement('div'))
237+
expect(
238+
'expose() should be passed a plain object, received ref'
239+
).toHaveBeenWarned()
240+
})
241+
242+
test('warning for array', () => {
243+
const Comp = defineComponent({
244+
setup(_, { expose }) {
245+
expose(['focus'])
246+
return () => null
247+
}
248+
})
249+
render(h(Comp), nodeOps.createElement('div'))
250+
expect(
251+
'expose() should be passed a plain object, received array'
252+
).toHaveBeenWarned()
253+
})
254+
255+
test('warning for function', () => {
256+
const Comp = defineComponent({
257+
setup(_, { expose }) {
258+
expose(() => null)
259+
return () => null
260+
}
261+
})
262+
render(h(Comp), nodeOps.createElement('div'))
263+
expect(
264+
'expose() should be passed a plain object, received function'
265+
).toHaveBeenWarned()
266+
})
228267
})

packages/runtime-core/src/component.ts

+21-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { VNode, VNodeChild, isVNode } from './vnode'
22
import {
3+
isRef,
34
pauseTracking,
45
resetTracking,
56
shallowReadonly,
@@ -47,6 +48,7 @@ import {
4748
} from './componentEmits'
4849
import {
4950
EMPTY_OBJ,
51+
isArray,
5052
isFunction,
5153
NOOP,
5254
isObject,
@@ -913,8 +915,25 @@ export function createSetupContext(
913915
instance: ComponentInternalInstance
914916
): SetupContext {
915917
const expose: SetupContext['expose'] = exposed => {
916-
if (__DEV__ && instance.exposed) {
917-
warn(`expose() should be called only once per setup().`)
918+
if (__DEV__) {
919+
if (instance.exposed) {
920+
warn(`expose() should be called only once per setup().`)
921+
}
922+
if (exposed != null) {
923+
let exposedType: string = typeof exposed
924+
if (exposedType === 'object') {
925+
if (isArray(exposed)) {
926+
exposedType = 'array'
927+
} else if (isRef(exposed)) {
928+
exposedType = 'ref'
929+
}
930+
}
931+
if (exposedType !== 'object') {
932+
warn(
933+
`expose() should be passed a plain object, received ${exposedType}.`
934+
)
935+
}
936+
}
918937
}
919938
instance.exposed = exposed || {}
920939
}

0 commit comments

Comments
 (0)