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).toBeTruthy()
|
||||||
expect(childRef.value.foo).toBe(1)
|
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 let isInSSRComponentSetup = false
|
||||||
|
|
||||||
export function setupComponent(
|
export function setupComponent(
|
||||||
@ -518,8 +522,8 @@ export function setupComponent(
|
|||||||
) {
|
) {
|
||||||
isInSSRComponentSetup = isSSR
|
isInSSRComponentSetup = isSSR
|
||||||
|
|
||||||
const { props, children, shapeFlag } = instance.vnode
|
const { props, children } = instance.vnode
|
||||||
const isStateful = shapeFlag & ShapeFlags.STATEFUL_COMPONENT
|
const isStateful = isStatefulComponent(instance)
|
||||||
initProps(instance, props, isStateful, isSSR)
|
initProps(instance, props, isStateful, isSSR)
|
||||||
initSlots(instance, children)
|
initSlots(instance, children)
|
||||||
|
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
import { ComponentInternalInstance, Data } from './component'
|
import {
|
||||||
|
ComponentInternalInstance,
|
||||||
|
Data,
|
||||||
|
isStatefulComponent
|
||||||
|
} from './component'
|
||||||
import { nextTick, queueJob } from './scheduler'
|
import { nextTick, queueJob } from './scheduler'
|
||||||
import { instanceWatch, WatchOptions, WatchStopHandle } from './apiWatch'
|
import { instanceWatch, WatchOptions, WatchStopHandle } from './apiWatch'
|
||||||
import {
|
import {
|
||||||
@ -207,8 +211,11 @@ type PublicPropertiesMap = Record<string, (i: ComponentInternalInstance) => any>
|
|||||||
*/
|
*/
|
||||||
const getPublicInstance = (
|
const getPublicInstance = (
|
||||||
i: ComponentInternalInstance | null
|
i: ComponentInternalInstance | null
|
||||||
): ComponentPublicInstance | null =>
|
): ComponentPublicInstance | ComponentInternalInstance['exposed'] | null => {
|
||||||
i && (i.proxy ? i.proxy : getPublicInstance(i.parent))
|
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), {
|
const publicPropertiesMap: PublicPropertiesMap = extend(Object.create(null), {
|
||||||
$: i => i,
|
$: i => i,
|
||||||
@ -219,7 +226,7 @@ const publicPropertiesMap: PublicPropertiesMap = extend(Object.create(null), {
|
|||||||
$slots: i => (__DEV__ ? shallowReadonly(i.slots) : i.slots),
|
$slots: i => (__DEV__ ? shallowReadonly(i.slots) : i.slots),
|
||||||
$refs: i => (__DEV__ ? shallowReadonly(i.refs) : i.refs),
|
$refs: i => (__DEV__ ? shallowReadonly(i.refs) : i.refs),
|
||||||
$parent: i => getPublicInstance(i.parent),
|
$parent: i => getPublicInstance(i.parent),
|
||||||
$root: i => i.root && i.root.proxy,
|
$root: i => getPublicInstance(i.root),
|
||||||
$emit: i => i.emit,
|
$emit: i => i.emit,
|
||||||
$options: i => (__FEATURE_OPTIONS_API__ ? resolveMergedOptions(i) : i.type),
|
$options: i => (__FEATURE_OPTIONS_API__ ? resolveMergedOptions(i) : i.type),
|
||||||
$forceUpdate: i => () => queueJob(i.update),
|
$forceUpdate: i => () => queueJob(i.update),
|
||||||
|
Loading…
Reference in New Issue
Block a user