Reputation: 1799
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://v2.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)
}
}
Upvotes: 6
Views: 13487
Reputation: 53185
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:
ref
special attribute: <line-chart ref="myLineChart"></line-chart>
this.$refs.myLineChart
.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>
Upvotes: 16
Reputation: 734
You need to add the greet() method to the chartjs.vue component, instead of chartsjsline.
Upvotes: 1