【问题标题】:Overriding a component method覆盖组件方法
【发布时间】:2017-03-30 11:31:33
【问题描述】:

我正在使用VueCharts,这是一个用于 vue 的 Google Charts 插件。

我正在尝试为图表提供更新的 Material Design 外观。我尝试将“google.charts.Bar”传递给图表类型道具,它确实有效。但是,许多选项都被忽略了,因为正如Google Charts docs 中所述,选项对象需要使用google.charts.Bar.convertOptions(options) 进行转换,而插件不会这样做。

查看源代码,该插件安装了一个“vue-chart”组件。该组件使用ChartWrapper 处理加载图表库,如下所示:

methods: {
    buildWrapper (chartType, dataTable, options, containerId) {
      let wrapper = new google.visualization.ChartWrapper({
        chartType: chartType,
        dataTable: dataTable,
        options: options,
        containerId: containerId
      })

      return wrapper
    },

所以我只需要重写此方法以在将选项传递给 ChartWrapper 之前对其进行转换。

但是怎么做呢?我还没有找到一种方法来简单地覆盖 vue 文档中的组件方法。我可以创建一个新组件并将转换后的选项向下传递,但我需要访问 google 对象,该对象仅由插件在内部加载。

我也读过我可以使用 mixins,但不清楚如何使用。这不起作用:

Vue.component('MyCustomChart', {
    mixins: ['vue-chart'],
    methods: {
        buildWrapper (chartType, dataTable, options, containerId) {
            let wrapper = new google.visualization.ChartWrapper({
                chartType: chartType,
                dataTable: dataTable,
                options: google.charts.Bar.convertOptions(options), // that's all I need
                containerId: containerId
            })

            return wrapper
        },
    }
})

[Vue 警告]:无法挂载组件:未定义模板或渲染函数。 (在 MyCustomChart 中找到)

【问题讨论】:

    标签: vuejs2 google-visualization


    【解决方案1】:

    你可以使用Vue的extend方法自定义插件组件。

    在你的情况下:

    import VueCharts from 'vue-charts'  
    Vue.use(VueCharts);
    
    const Base = Vue.options.components["vue-chart"];
    const CustomChart = Base.extend({
      methods: {
        buildWrapper (chartType, dataTable, options, containerId) {
          let wrapper = new google.visualization.ChartWrapper({
            chartType: chartType,
            dataTable: dataTable,
            options: google.charts.Bar.coverOptions(options),
            containerId: containerId
          })
    
          return wrapper
        },
      })
    }
    
    Vue.component('MyCustomChart', CustomChart);
    

    (感谢 Bert Evans 指出您需要在扩展自定义之前从 Vue.options.components 引用基本组件)

    【讨论】:

    • 我不确定这是否可行。 vue-charts 是一个插件。 vue-chart 是一个全局添加的组件。
    • 它对我有用。如果vue-chart 组件提供了一个属性来指定选项,那么重写该方法不是可行的方法。但是,解决这个问题,这就是我将如何覆盖组件插件中的方法。
    • 您是否有理由选择 lodash 而不是 Vue.extend?
    • 如何使用组件插件来做到这一点?
    • 这种情况下,扩展两次; const Base = Vue.extend(VueChart),然后是 const CustomChart = Base.extend({...})。无论如何,我只是好奇。谢谢:)
    【解决方案2】:

    我对此进行了一些尝试,并在上面误导了@thanksd 关于扩展内容的建议。一种可行的方法是:

    import VueChart from "vue-charts";
    
    Vue.use(VueChart);
    
    const BaseChart = Vue.options.components["vue-chart"];
    const CustomChart = BaseChart.extend({
      methods:{
        buildWrapper (chartType, dataTable, options, containerId) {
          let wrapper = new google.visualization.ChartWrapper({
            chartType: chartType,
            dataTable: dataTable,
            options: google.charts.Bar.convertOptions(options),
            containerId: containerId
          })
    
          return wrapper
        }
      }
    });
    
    Vue.component("custom-chart", CustomChart);
    

    进一步说明

    正如我所想,通过 Vue 的原生扩展或通过 lodash 扩展 VueChart,都不会达到预期的效果。导入 VueChart 的结果是 plugin definitionlodashVue 都乐意接受它作为要扩展的对象,但都不会生成 Vue 组件。尝试使用任一结果将导致问题中提到的错误,“未定义模板或渲染函数”。这个错误是绝对正确的;扩展VueChart 使用单一方法扩展安装功能。

    那么如何让对象扩展呢? vue-charts 不会暴露它。安装只需调用Vue.component('vue-chart', Chart)

    幸运的是,Vue 通过Vue.options.components 使全局安装的组件。通过扩展Vue.options.components["vue-chart"],我们得到了正确的 Vue 组件定义。

    最后,我很惊讶@RegularEverydayNormalGuy 无法使用google。它必须可用; vue-chart 使用它。但他是对的,它立即不可用。 vue-chart 异步加载脚本。同样,遗憾的是,该插件不会以任何方式提供给您,it just initializes itself after it's asynchronously loaded。有一些方法可以解决这个问题,但此时您应该提交一个拉取请求。

    原答案

    optionsvue-chart 上的属性。为什么不直接传入转换后的选项?

    new Vue({
        data:{
            convertedOptions: google.charts.Bar.convertOptions({<my options>})
        }
    })
    

    在模板中

    <vue-chart :options="convertedOptions"></vue-chart>
    

    【讨论】:

    • @RegularEverydayNormalGuy 你说得对。它不是立即可用的。
    • 感谢您的详细解答。希望我能同时接受。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-04
    • 2017-05-10
    • 1970-01-01
    相关资源
    最近更新 更多