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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user