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()
+ })
})
import { VNode, VNodeChild, isVNode } from './vnode'
import {
+ isRef,
pauseTracking,
resetTracking,
shallowReadonly,
} from './componentEmits'
import {
EMPTY_OBJ,
+ isArray,
isFunction,
NOOP,
isObject,
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 || {}
}