26

I have a parent component where I need to call a method that exists in one of its child components:

<template>
  <div>
    <button @click="callChildMethod">
    <child-component ref="child" />
  </div>
</template>
<script>
  setup(props) {
    const child = ref(null)
    const callChildMethod = () => {
      child.doSomething()
    }

    return {
      child,
      callChildMethod
    }
  }
</script>
  

The child component contains the doSomething method:

const doSomething = () => { console.log('calling method....') }

Since I'm using the VueJS3 and the Composition API, my approach was to use a template ref to call the method in the child component. Obviously is not working but I can't see what I'm missing. Does someone have a clue about this one? Thanks in advance

3 Answers 3

60

P.s. for <script setup> (Composition API) need to use defineExpose

https://v3.vuejs.org/api/sfc-script-setup.html#defineexpose

Parent component:

<script setup>
...
const childred = ref();

childred.value.doSomething()
</script>

<template>
  <ChildrenComponent ref="childred" />
</template>

ChildrenComponent:

<script setup>
...
function doSomething(){
  console.log(1);
}

defineExpose({
  doSomething,
});

</script>

<template>
  <div>123</div>
</template>

Sign up to request clarification or add additional context in comments.

5 Comments

Great, when using script setup syntax just we have to do this way
thanks a lot man! All day I was searching for a solution. nobody mentioned defineExpose!!!! you are the best!!!!!!!
Seems not working on Vue 3 5.0.8 Composition API <script setup>, error: Cannot read properties of undefined (reading 'doSomething')
@BassemRamzy seems like a problem with your components
@BassemRamzy I had exactly the same problem. The only way I made it work was to inspect the ref object and I found that you can call the function from childred.value.$.exposed.doSomething()
19

You're missing the value field in your ref, it should be :

 const callChildMethod = () = {
  child.value.doSomething()
}

Edit amazing-cori-5hgi9

If the child component is defined using the script setup syntax you should use defineExpose to expose the method to the outside

<script setup>

function doSomething(){
  //......
}

defineExpose({
  doSomething,
});

</script>

Parent :

<template>
  <div>
    <button @click="callChildMethod">
    <child-component ref="child" />
  </div>
</template>
<script>
  setup(props) {
    const child = ref(null)
    const callChildMethod = () => {
      child.doSomething()
    }

    return {
      child,
      callChildMethod
    }
  }
</scrip>

or

<template>
  <div>
    <button @click="callChildMethod">
    <child-component ref="child" />
  </div>
</template>
<script setup>

    const child = ref(null)
    const callChildMethod = () => {
      child.doSomething()
    }


</scrip>

2 Comments

The function statement const callChildMethod = () = { should be const callChildMethod = () => { in that whay it becomes an arrow-function
Getting an error "child.doSomething is not a function", on latest play.vuejs.org
2

Using ref generates an error with me, I found out another handshaking way (using watch for a property set by a reactive variable in parent, emitting back the results) that's fine with me, and gives more control, in case needed:

Child Component:

const props = defineProps({
  callRequested: {
    type: Boolean,
  },
});
function myFunc() {
  let result = false ;
  // Do your stuff
  return result;
}
const emit = defineEmits(['funcResult']);
watch(
  () => props.callRequested,
  (newVal) => {
    console.log(`newVal is: ${newVal}`);
    if (newVal)
      emit('funcResult', myFunc());
  }
)

Parent Component:

<template>
  <div>
    <button @click="callChildMethod">
    <child-component 
     :call-requested="state.callRequested" 
     :@func-result="funcResult"
    />
  </div>
</template>
<script setup>
const state = reactive({
  callRequested: false,
});
function callChildMethod() {
  state.callRequested= true;
}
function funcResult(param) {
  state.callRequested = false;  // Reset it for next call
  // Do parent stuff based on param = function result
}
</script>

1 Comment

ref worked with me only after I defineExpose a variable (in addition to the function).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.