Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trigger child component method from parent event

I am very new to VueJS and JavaScript and your help would be much appreciated.

My method "greet" is not working and I am unsure why. When I click on the button "change to bar" I get the error:

[Vue warn]: Property or method "greet" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

found in

---> <Chatjsvue> at src\components\vueChartjs\Chatjsvue.vue
       <App> at src\App.vue
         <Root>

chartjs.vue

<template src="../../views/chartjshtml/chartsjs.html"></template>
<script>
  import LineChart from '@/assets/javascripts/chartjsline'

    export default {
    components: {
      'line-chart': LineChart 
    }
  }
</script>

chartsjs.html

<div class="wrapper">
    <div>
     <ul>
       <li><button v-on:click="greet()">change to bar</button></li>
       <li><line-chart></line-chart></li>
     </ul>
    </div>
</div>

chartsjsline.js

import { Line } from 'vue-chartjs'

export default {
  extends: Line,
  data() {
      return {
         datacollection: {
            //Data to be represented on x-axis
            labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
            datasets: [{
               label: 'Activities ChartJS Line',
               backgroundColor: '#f87979',
               pointBackgroundColor: 'white',
               borderWidth: 1,
               pointBorderColor: '#249EBF',
               //Data to be represented on y-axis
               data: [40, 20, 30, 50, 90, 10, 20, 40, 50, 70, 90, 100]
            }]
         },
         //Chart.js options that controls the appearance of the chart
         options: {
            scales: {
               yAxes: [{
                  ticks: {
                     beginAtZero: true
                  },
                  gridLines: {
                     display: true
                  }
               }],
               xAxes: [{
                  gridLines: {
                     display: false
                  }
               }]
            },
            legend: {
               display: true
            },
            responsive: true,
            maintainAspectRatio: false
         },
      }
   },
   methods: {
      greet() {
        alert('hello');
      }
    },
    mounted() {
      //renderChart function renders the chart with the datacollection and options object.
      this.renderChart(this.datacollection, this.options)
   }
}
like image 788
ARTLoe Avatar asked May 17 '18 11:05

ARTLoe


People also ask

How do you trigger event from parent to child component in react?

To pass an onChange event handler to a child component in React: Define the event handler function in the parent component. Pass it as a prop to the child component, e.g. <Child handleChange={handleChange} /> . Set it to the onChange prop on the input field in the child.

How do you call a child component method from parent in Salesforce?

createAccount(param1, param2); where param1 and param2 are the parameters that we are passing to the createAccount method of Child Component. And this is enough to call the method of Child from Parent Component. We can also return some value from the methods of Child Component.

How do you call a method in a child component from parent component Vuejs?

To call a method in a child component with Vue. js, we can pass in a prop from the parent component to its child. Then in the child component, we watch the prop's value and run the method we want. in the child component to register the testProp prop and add the sayHello method.


2 Answers

Your <line-chart> component (instance of LineChart) is a child component of your Chatjsvue component.

The child methods remain bound to those instances.

However it is extremely easy from the parent component to access its child component, and from there to execute their methods:

  1. Keep a reference to your child component, using the ref special attribute: <line-chart ref="myLineChart"></line-chart>
  2. Within a parent method, access the referred child using this.$refs.myLineChart.
  3. Then you have access to everything on this child instance, including its methods: this.$refs.myLineChart.greet()

Working example:

Vue.component('chart-js', {
  template: '#chartjs',
  methods: {
    lineChildGreet() {
      // Access the child component through $refs.
      // Then you can execute its methods.
      this.$refs.myLineChart.greet();
    },
  },
});

Vue.component('line-chart', {
  template: '#lineChart',
  methods: {
    greet() {
      alert('hello');
    },
  },
});

var app = new Vue({
  el: '#app',
});
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
  <chart-js></chart-js>
</div>

<template id="chartjs">
  <div class="wrapper">
    <div>
     <ul>
       <li><button v-on:click="lineChildGreet">greet on child component</button></li>
       <!-- Keep a REFerence to the child component -->
       <li><line-chart ref="myLineChart"></line-chart></li>
     </ul>
    </div>
  </div>
</template>

<template id="lineChart">
  <span>LineChart</span>
</template>
like image 164
ghybs Avatar answered Sep 18 '22 14:09

ghybs


You need to add the greet() method to the chartjs.vue component, instead of chartsjsline.

like image 32
Luke Ramsden Avatar answered Sep 17 '22 14:09

Luke Ramsden