首页 > 解决方案 > Vue调用另一个组件文件方法

问题描述

我得到了文件'PieChart.vue'。另一方面,我有另一个文件调用 dashboard.vue 但我不能调用 PieChart.vue -> "genChart" 函数。是否可以调用该函数?我想刷新图表。这是因为我使用 vuetify 选项卡,但 vue 图表 js 似乎无法在 vuetify 选项卡中呈现图表。它需要重新渲染才能显示图表。这种情况有什么解决办法吗?

饼图.vue:

<script>
import { Pie } from "vue-chartjs";

export default {
    extends: Pie,
    name: "v-PieChart",
    props: {
        data: Array,
        label: Array,
        color: Array,
    },
    watch: {
        data: function (newData, oldData) {
            this.debouncedGenChart();
        },
    },
    created: function () {
        this.debouncedGenChart = _.debounce(this.genChart, 500);
    },
    methods: {
        genChart: function () {
            this.renderChart(
                {
                    labels: this.label,
                    datasets: [
                        {
                            backgroundColor: this.color,
                            data: this.data,
                        },
                    ],
                },
                { responsive: true, maintainAspectRatio: false }
            );
        },
    },
};
</script>

仪表板.vue:

<v-tabs>
    <v-tab
        :href="`#tab-AM`"
        @click="$refs.leaveChartAM.genChart()"
    >AM</v-tab>
    <v-tab
        :href="`#tab-PM`"
        @click="$refs.leaveChartPM.genChart()"
    >PM</v-tab>
    <v-tab-item :value="'tab-AM'">
        <v-PieChart
            :data="charts.leave.data"
            :label="charts.leave.label"
            :color="['#00E676', '#66BB6A', '#AED581']"
            ref="leaveChartAM"
        ></v-PieChart>
    </v-tab-item>
    <v-tab-item :value="'tab-PM'">
        <v-PieChart
            :data="charts.leave.data"
            :label="charts.leave.label"
            :color="['#00E676', '#66BB6A', '#AED581']"
            ref="leaveChartPM"
        ></v-PieChart>
    </v-tab-item>
</v-tabs>

标签: vue.jsvuetify.jsvue-chartjs

解决方案


您可以实现自定义事件来调用组件之间的函数。我已经说明了两种可用于绑定事件和调用函数的方法。

方法一


保留单独的 Vue 实例,仅用于注册自定义事件。将它分配给窗口,以便可以从任何地方访问它

// Initiate
window.Notifier = new Vue();

// Bind event
window.Notifier.$on('regenPieChartMethod1', function(message){
    //code block
});

// Call event from any component
window.Notifier.$emit('regenPieChartMethod1', message);

方法二


将事件绑定到父组件,这样子组件就可以访问它

// Bind event
this.$parent.$on('regenPieChartMethod2', function(message){
    //code block
});

// Call event from child component
this.$parent.$emit('regenPieChartMethod2', message);

您可以使用适合您的实施的任何选项

完整的解决方案

// Use a seperate Vue instance only for event
window.Notifier = new Vue();

Vue.component('dashboard', {
  methods: {
  
    callRegenPieChartMethod1 () {
    
      var message = 'Pie Chart data is regenerated using method 1';
        window.Notifier.$emit('regenPieChartMethod1', message);
    },
    
    callRegenPieChartMethod2 () {
    
      var message = 'Pie Chart data is regenerated using method 2';
      this.$parent.$emit('regenPieChartMethod2', message);
    }
  },
  template: '<div><h4>Dashboard Component</h4><button @click="callRegenPieChartMethod1">Refresh Pie Chart - Method 1</button> <button @click="callRegenPieChartMethod2">Refresh Pie Chart - Method 2</button></div>',
});


Vue.component('piechart', {
  data() {
    return {
      message: 'This is initial data of the pie chart!'
    };
  },
  mounted() {
    var _t = this;
    
    // use seperate Vue instance to bind event
    window.Notifier.$on('regenPieChartMethod1', function(message){
        _t.genChart(message);
    });
    
    // bind event to the parent
    this.$parent.$on('regenPieChartMethod2', function(message){
        _t.genChart(message);
    });
  },
  methods: {
    genChart (message) {
      this.message = message;
    }
  },
  template: '<div><h4>Pie Chart Component</h4> <p>Message : {{message}}</p></div>',
});

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


推荐阅读