首先,我想说这个问题不是一成不变的,因为我很愿意尝试其他建议,因为我可能已经完全错过了一种合适的方法。
我在JSX中使用Vue-ChartJs,但想达到一个点,在应用程序开始时,我不必扩展我需要的每个图表组件,例如:
// Line bar component.
Vue.component('line-chart', {
extends: VueChartJs.Line,
props: ['data', 'options'],
mounted() {
this.renderChart(this.data, this.options)
}
});
相反,我想基于一个可能会决定扩展内容的道具来动态扩展组件:
const getChart = (type) => {
if (type === 'bar') {
return VueChartJs.Bar;
};
};
Vue.component('chart', {
props: ['data', 'options', 'type'],
extends: () => {
getChart(this.type)
},
mounted() {
this.renderChart(this.data, this.options)
}
})
此方法当前不起作用,因为in扩展:它返回的错误t是undefined,未设置“ this”。
对于可能的解决方案,有什么建议吗? 预先感谢。
答案 0 :(得分:1)
在您的示例中,type
属性有效地决定使用哪个组件。内置属性is
更适合此工作。请注意,这里我仍在注册所有组件,但是使用util函数会使代码非常简短。
<div id="app">
<div>
<!-- think of :is like the :type property in your example, it serves the same purpose -- deciding which component to use -->
<component :is="chartTypeLine" :data="chartData" :options="chartOptions"></component>
<component :is="chartTypeBar" :data="chartData" :options="chartOptions"></component>
</div>
</div>
<script src="https://vuejs.org/js/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
<script src="https://unpkg.com/vue-chartjs/dist/vue-chartjs.min.js"></script>
<script>
const getChart = (type) => {
switch (type) {
case 'line-chart':
return VueChartJs.Line;
case 'bar-chart':
return VueChartJs.Bar;
default:
throw new Error("wrong chart type");
}
};
const chartTypes = ['line-chart', 'bar-chart'];
//this makes registering all those components easier.
chartTypes.forEach(type => {
Vue.component(type, {
extends: getChart(type),
props: ['data', 'options'],
mounted () {
this.renderChart(this.data, this.options)
}
})
});
new Vue({
el: '#app',
data: {
chartData: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [
{
backgroundColor: '#f87979',
data: [40, 39, 10, 40, 39, 80, 40]
}
]
},
chartOptions: {responsive: true, maintainAspectRatio: false},
chartTypeLine: 'line-chart',
chartTypeBar: 'bar-chart'
}
})
</script>
答案 1 :(得分:0)
除了先前的答案,我今天早上还发现了另一种方法。第一次运行JSX文件时,它使用相同的foreach循环通过一个对象实例化每种图表类型,这会将它们全部注册在准备使用的范围内。
const chartNames = [
{
name: 'line-chart',
type: VueChartJs.Line
}, {
name: 'bar-chart',
type: VueChartJs.Bar
},
{
name: 'horizontal-bar-chart',
type: VueChartJs.HorizontalBar
},
{
name: 'doughnut-chart',
type: VueChartJs.Doughnut
},
{
name: 'pie-chart',
type: VueChartJs.Pie
},
{
name: 'radar-chart',
type: VueChartJs.Radar
},
{
name: 'polar-area-chart',
type: VueChartJs.PolarArea
},
{
name: 'bubble-chart',
type: VueChartJs.Bubble
},
{
name: 'scatter-chart',
type: VueChartJs.Scatter
}];
const registerCharts = (chartNames) => {
chartNames.forEach((chartName) => {
Vue.component(chartName.name, {
extends: chartName.type,
mixins: [VueChartJs.mixins.reactiveProp],
props: {
options: Object
},
methods: {
// Used in the alternate render version, this updates the chart in question.
update() {
this.$data._chart.update()
}
},
mounted() {
this.renderChart(this.chartData, this.options)
}
});
})
};
registerCharts(chartNames);
答案 2 :(得分:0)
我喜欢这个
图表.js
import VueChartJs from 'vue-chartjs'
import Vue from 'vue'
const getChart = (type) => {
switch (type) {
case 'LineChart':
return VueChartJs.Line
case 'BarChart':
return VueChartJs.Bar
case 'PieChart':
return VueChartJs.Pie
default:
throw new Error('wrong chart type')
}
}
// generate component via fun
// it mean that you will generate as many components as you need
export default (type) => {
return Vue.component(type, {
extends: getChart(type),
name: type,
props: ['data', 'options'],
mounted () {
this.renderChart(this.data, this.options)
}
})
}
index.vue
<template>
..
<PieChart
:data="testData"
:options="options"
/>
..
</template>
<script>
import Chart from '~/components/UI/Chart/index'
..
export default {
components: {
PieChart: Chart('PieChart')
}
}
</script>