【问题标题】:Trigger child component method from parent event从父事件触发子组件方法
【发布时间】:2018-10-27 15:46:18
【问题描述】:

我对 VueJS 和 JavaScript 非常陌生,非常感谢您的帮助。

我的方法“greet”不起作用,我不确定原因。当我单击“更改为栏”按钮时,出现错误:

[Vue 警告]:属性或方法“greet”未在实例上定义,但在渲染期间被引用。通过初始化该属性,确保此属性是反应性的,无论是在数据选项中,还是对于基于类的组件。请参阅:https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties

发现于

---> <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)
   }
}

【问题讨论】:

    标签: vue.js vue-component


    【解决方案1】:

    您的&lt;line-chart&gt; 组件(LineChart 的实例)是您的Chatjsvue 组件的 组件。

    子方法仍然绑定到这些实例。

    但是from the parent component to access its child component 非常容易,并从那里执行他们的方法:

    1. 使用ref 特殊属性保留对子组件的引用:&lt;line-chart ref="myLineChart"&gt;&lt;/line-chart&gt;
    2. 在父方法中,使用this.$refs.myLineChart 访问被引用的子方法。
    3. 然后您可以访问此子实例上的所有内容,包括其方法:this.$refs.myLineChart.greet()

    工作示例:

    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>

    【讨论】:

    • 如果我有&lt;span @click="handleClick"&gt;LineChart&lt;/span&gt;怎么办?如何从“chart-js”组件触发组件模板的根元素上的点击事件?
    • @webprogrammer 你应该用你的问题的具体细节将它作为一个新问题,而不是评论一个与你所说的你试图实现的不同的旧帖子。
    • ghybs,好的,谢谢!但我已经找到了解决方案。我认为我的问题与您的回答有关。很抱歉打扰您了。
    【解决方案2】:

    你需要在 chartjs.vue 组件中添加 greet() 方法,而不是 chartjsline。

    【讨论】:

    • 谢谢。我认为可以通过 chartjsline.js 文件调用这些方法,因为我在 .vue 文件中使用了 import LineChart from '@/assets/javascripts/chartjsline' 但我想这不起作用 - 我现在已经在 .vue 文件中调用了该方法 - 谢谢跨度>
    猜你喜欢
    • 2020-04-16
    • 2018-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-15
    • 1970-01-01
    相关资源
    最近更新 更多