expect(childRef.value).toBeTruthy()
expect(childRef.value.foo).toBe(1)
})
+
+ test('with $parent/$root', () => {
+ const Child = defineComponent({
+ render() {
+ expect((this.$parent! as any).foo).toBe(1)
+ expect((this.$parent! as any).bar).toBe(undefined)
+ expect((this.$root! as any).foo).toBe(1)
+ expect((this.$root! as any).bar).toBe(undefined)
+ }
+ })
+
+ const Parent = defineComponent({
+ expose: [],
+ setup(_, { expose }) {
+ expose({
+ foo: 1
+ })
+ return {
+ bar: 2
+ }
+ },
+ render() {
+ return h(Child)
+ }
+ })
+ const root = nodeOps.createElement('div')
+ render(h(Parent), root)
+ })
})
}
}
+export function isStatefulComponent(instance: ComponentInternalInstance) {
+ return instance.vnode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT
+}
+
export let isInSSRComponentSetup = false
export function setupComponent(
) {
isInSSRComponentSetup = isSSR
- const { props, children, shapeFlag } = instance.vnode
- const isStateful = shapeFlag & ShapeFlags.STATEFUL_COMPONENT
+ const { props, children } = instance.vnode
+ const isStateful = isStatefulComponent(instance)
initProps(instance, props, isStateful, isSSR)
initSlots(instance, children)
-import { ComponentInternalInstance, Data } from './component'
+import {
+ ComponentInternalInstance,
+ Data,
+ isStatefulComponent
+} from './component'
import { nextTick, queueJob } from './scheduler'
import { instanceWatch, WatchOptions, WatchStopHandle } from './apiWatch'
import {
*/
const getPublicInstance = (
i: ComponentInternalInstance | null
-): ComponentPublicInstance | null =>
- i && (i.proxy ? i.proxy : getPublicInstance(i.parent))
+): ComponentPublicInstance | ComponentInternalInstance['exposed'] | null => {
+ if (!i) return null
+ if (isStatefulComponent(i)) return i.exposed ? i.exposed : i.proxy
+ return getPublicInstance(i.parent)
+}
const publicPropertiesMap: PublicPropertiesMap = extend(Object.create(null), {
$: i => i,
$slots: i => (__DEV__ ? shallowReadonly(i.slots) : i.slots),
$refs: i => (__DEV__ ? shallowReadonly(i.refs) : i.refs),
$parent: i => getPublicInstance(i.parent),
- $root: i => i.root && i.root.proxy,
+ $root: i => getPublicInstance(i.root),
$emit: i => i.emit,
$options: i => (__FEATURE_OPTIONS_API__ ? resolveMergedOptions(i) : i.type),
$forceUpdate: i => () => queueJob(i.update),