fix(runtime-core): align $parent/$root with the template ref when using expose (#3158)
This commit is contained in:
parent
3efa2aff13
commit
f43a3b0beb
@ -141,4 +141,32 @@ describe('api: expose', () => {
|
||||
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)
|
||||
})
|
||||
})
|
||||
|
@ -510,6 +510,10 @@ export function validateComponentName(name: string, config: AppConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
export function isStatefulComponent(instance: ComponentInternalInstance) {
|
||||
return instance.vnode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT
|
||||
}
|
||||
|
||||
export let isInSSRComponentSetup = false
|
||||
|
||||
export function setupComponent(
|
||||
@ -518,8 +522,8 @@ 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)
|
||||
|
||||
|
@ -1,4 +1,8 @@
|
||||
import { ComponentInternalInstance, Data } from './component'
|
||||
import {
|
||||
ComponentInternalInstance,
|
||||
Data,
|
||||
isStatefulComponent
|
||||
} from './component'
|
||||
import { nextTick, queueJob } from './scheduler'
|
||||
import { instanceWatch, WatchOptions, WatchStopHandle } from './apiWatch'
|
||||
import {
|
||||
@ -207,8 +211,11 @@ type PublicPropertiesMap = Record<string, (i: ComponentInternalInstance) => any>
|
||||
*/
|
||||
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,
|
||||
@ -219,7 +226,7 @@ const publicPropertiesMap: PublicPropertiesMap = extend(Object.create(null), {
|
||||
$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),
|
||||
|
Loading…
Reference in New Issue
Block a user