2

I have a 3 level deep component setup that looks like this.

- container
  - section-1 // section1Ref
    - form-1 // form1Ref

The container component will trigger the submit method in the section-1 via this.$refs.section1Ref.submit().

The submit method in the section component will then call the submit method in the form-1 component like this.$refs.form1Ref.submit()

I am getting this error in this.$refs.form1Ref.submit() invokation.

this.$refs.form1Ref.submit is not a function

Tho I am 100% sure that it's defined in the methods object of the form-1 component.

I noticed that this is happening when the ref is 3 levels deep.

4
  • IMO using $refs like this is an anti pattern. try using event instead vuejs.org/v2/guide/… Commented May 24, 2019 at 7:54
  • Thanks @JacobGoh I want the top most or the parent container to trigger all of the submit for it's child components. Would mind suggesting a way of using events? Commented May 24, 2019 at 8:10
  • I had a similar issue, when I have multiple elements referenced, the child elements don't initialize as refs. I think having them all as separate components would work because it will wait to initialize things at each layer, but when they're all in the same component it seems to break. Did you ever resolve this? Commented Mar 20, 2021 at 3:07
  • It turns out that the v-for keys on my array of components were being initialized too late which broke the refs somehow. After ensuring that the v-for array keys existed in the objects the refs were defined for me. Commented Mar 20, 2021 at 3:41

1 Answer 1

1

It worked for me, Here is my sample code

Vue.component('sec', {
  template: `
  <div>section
    <br>
    <form1 ref="form"></form1>
  </div>`,
  methods: {
    callSection() {
      this.$refs.form.callForm();
    }
  }
});
Vue.component('form1', {
  template: `<div>form</div>`,
  methods: {
    callForm() {
      console.log('am called inside form')
    }
  }
});

Vue.component('container', {
  template: `
  <div>
    <button @click="clickMe">Click me</button>
    <br>
    <sec ref="section"></sec>
  </div>`,
  methods: {
    clickMe() {
      this.$refs.section.callSection();
    }
  }
});

// create a new Vue instance and mount it to our div element above with the id of app
Vue.config.devtools = false;
Vue.config.productionTip = false;

var vm = new Vue({
  el: '#app'
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <container />
</div>

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

Comments

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.