SoFunction
Updated on 2025-04-13

Five solutions for Vue3 parent component access to child component methods/properties

1. ref + defineExpose (recommended solution)

Accurate access through a combined API, which is the core method officially recommended by Vue3:

<!-- Subcomponents   -->
<script setup>
import { ref } from 'vue'
 
const childData = ref('Subcomponent data')
const childMethod = () => ('The method is triggered')
 
// Must be exposed to access by parent componentdefineExpose({
  childData,
  childMethod
})
</script>
 
<!-- Parent component   -->
<template>
  <Child ref="childRef" />
</template>
 
<script setup>
import { ref, onMounted } from 'vue'
const childRef = ref(null)
 
onMounted(() => {
  ()  // Output: Subcomponent data  ()           // Trigger subcomponent method})
</script>

Key points description:

  1. The subcomponent must passdefineExposeExplicit properties/methods
  2. Parent component passesPay attention to the life cycle timing when accessing
  3. Support TS type derivation (need to be used with TypeScript)

2. getCurrentInstance (alternative solution)

Suitable for advanced scenarios where access to component context is required:

// SubcomponentsdefineExpose({ customMethod: () => {} })
 
// Parent componentimport { getCurrentInstance } from 'vue'
 
const instance = getCurrentInstance()
const childComponent =  
() 

Notes:

  1. It belongs to the underlying API, and it is recommended to use the ref scheme first
  2. Component rendering order needs to be strictly guaranteed
  3. Problems may occur in SSR environment

3. Event-driven mode (props + emit)

Communication methods that comply with the principle of one-way data flow:

<!-- Subcomponents -->
<script setup>
defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
 
const updateData = (val) => {
  emit('update:modelValue', val)
}
</script>
 
<!-- Parent component -->
<Child :modelValue="parentData" @update:modelValue="handleUpdate"/>

Applicable scenarios:

  • One-way flow of data is required
  • Form components, etc. need two-way binding

4. Dependency injection mode (provide/inject)

Solve deep nested component access issues:

// Ancestor componentprovide('sharedData', ref('Responsible data'))
 
// Descendant componentsconst data = inject('sharedData')

Advantages:

  • Direct access across multiple layers of components
  • Implement state sharing with responsive API

5. Status Management Solution (Pinia/Vuex)

Access methods in global state management scenarios:

// store/ 
export const useUserStore = defineStore('user', {
  state: () => ({ userInfo: null })
})
 
//Arbitrary componentsconst store = useUserStore()
  = 'Global Data'

Applicable scenarios:

  • Need to share state across multiple components
  • State management of complex applications

Notes and best practices

  1. One-way data flow principle: Priority is given to props/emit method to pass data
  2. Encapsulation protection: The minimum API collection that the child component should explicitly expose
  3. Life cycle timing: Make sure to access ref after onMounted
  4. TypeScript Support: Use interface to define the exposure type

Plan comparison table

method Applicable level Responsive Maintenance cost Applicable scenarios
ref + defineExpose Father and son ✔️ Low Precise method call
provide/inject Cross-level ✔️ middle Deep component sharing
Event-driven Father and son ✔️ Low Data change notification
Status Management Global ✔️ high Complex application state sharing

This is the end of this article about the five solutions for Vue3 parent component access to child component methods/properties. For more information about Vue3 parent component access to child component methods, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!