2

Hey I am really new to VUE and for this project I have a button on one page which should trigger or call the function of another page. Everyone will be like why don't you have the button and function on same page as I am trying to learn basic part of how to call function of different page and then implement on my project. I am trying to make it easier and clear while I am asking question.

When I call the method function of chairPage.vue from homePage.vue, it throws an error saying world not defined on homePage.vue. Can anyone please explain why I am getting this error and what's the best way to solve this.

I have two pages one is homePage.vue and another one is chair.Vue. I have a button on homePage.vue which should call the method function of chairPage.vue.

Home Page

<template>
   <div id="homepage">
     <b-button variant="info" @click="buttonClicked()">Click</b-button>

     <chairComponent ref="world"/>

   </div>
</template>

<script>
  import chairComponent from '@/components/chair.vue';

  export default {
  props: [],
  
  methods:{
    buttonClicked(){
      this.$refs.world.hello();
    }
  }

  }
</script>

Chair Page

<template>
   <div id="chairComponent">
      <p v-if="displayText == '1'"> HELLO WORLD </p>
   </div>
</template>

<script>
  export default {
    props: ['world'],
    data(){
      return{
        displayText:'',
      }
    },
    methods:{
      hello(){
        console.log('inside child component hello function');
        this.displayText = '1';
      }
    }
  }
</script>

3 Answers 3

1

You can pass props to your child component, and there watch on props and call function:

Vue.component('Chair', {
  template: `
    <div id="chairComponent">
      <p v-if="displayText == '1'"> HELLO WORLD </p>
   </div>
  `,
  props: ['world'],
  data(){
   return{
    displayText:'',
   }
  },
  methods:{
    hello(){
      console.log('inside child component hello function');
      this.displayText = '1';
   }
  },
  watch: {
    world() {
      if (this.world) this.hello()
    }
  }
})

new Vue({
  el: '#demo',
  data() {
    return {
      val: null
    }
  },
  methods:{
    buttonClicked(){
      this.val = true
      setTimeout(() => {this.val = false},0)
    }
  }
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" />
<script src="//unpkg.com/vue@latest/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue-icons.min.js"></script>
<div id="demo">
 <div id="homepage">
   <b-button variant="info" @click="buttonClicked">Click</b-button>
   <chair :world="val" />
 </div>
</div>

7
  • Hey I tried to add the Vue.component on top of export default part and it throws an error saying Vue is not defined
    – Yahoo
    Commented Jan 28, 2022 at 16:54
  • @Yahoo hey mate, no don't do that just change your existing components to use props like in my example Commented Jan 28, 2022 at 17:00
  • I was able to call the function but it only trigger one time. Is there a way I can make each time the button CLICK is clicked it will print out console.log('INSIDE CHILD COMPONENT HELLO FUNCTION') .
    – Yahoo
    Commented Jan 28, 2022 at 17:31
  • 1
    try now pls just updated my answer (just added setTimeout(() => {this.val = false},0)) in buttonClicked method Commented Jan 28, 2022 at 17:52
  • 1
    sure, it means that you allow line above to be executed, (so setting the val which is prop that shows your message) then val is reset to null and you can again repeat call Commented Jan 28, 2022 at 18:06
1

It works perfectly fine in the below snippet

Vue.component('Chair', {
  template: `
    <div id="chairComponent">
   </div>
  `,
  data(){
   return{
    displayText:'',
   }
  },
  methods:{
    hello(){
      console.log('inside child component hello function');
   }
  },
})

new Vue({
  el: '#demo',
  methods:{
    buttonClicked(){
      this.$refs.world.hello();
    }
  }
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" />
<script src="//unpkg.com/vue@latest/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue-icons.min.js"></script>
<div id="demo">
 <div id="homepage">
   <b-button variant="info" @click="buttonClicked">Click</b-button>
   <chair ref="world" />
 </div>
</div>

I guess adding the components section in the homepage.vue might make it work

<template>
   <div id="homepage">
     <b-button variant="info" @click="buttonClicked()">Click</b-button>

     <chairComponent ref="world"/>

   </div>
</template>

<script>
  import chairComponent from '@/components/chair.vue';

  export default {
  props: [],
  // New changes added below 
  components: {
    chairComponent
  },
  methods:{
    buttonClicked(){
      this.$refs.world.hello();
    }
  }
  }
</script>
2
  • Hey I tried to add the Vue.component on top of export default part and it throws an error saying Vue is not defined
    – Yahoo
    Commented Jan 28, 2022 at 16:53
  • Don't do Vue.component, just follow the changes that I have done in homepage.vue
    – Amaarockz
    Commented Jan 28, 2022 at 18:14
0

You can $emit from children to parent https://v2.vuejs.org/v2/guide/components-custom-events.html

Child

hello () {
  ...//yours code
  this.$emit('customEvent', someValue)
}

Parent

<template>
  <child 
    @cutomEvent="function"
  />
<template>

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.