6

I have the following code in HTML (coded with Vue JS & Bootstrap):

<b-tabs card>
        <b-tab title="Followers" :title-link-class="'tab-title-class'">
              Page View graph here
        </b-tab>
        <b-tab title="Orders" :title-link-class="'tab-title-class'">
              Order Numbers graph here
        </b-tab>
        <b-tab title="Sales" :title-link-class="'tab-title-class'">
              <sales-analytics></sales-analytics>
        </b-tab>
        <b-tab title="Profit" :title-link-class="'tab-title-class'">
              Earning graph here
        </b-tab>
</b-tabs>

The card contains 4 tabs, one of which is titled "Sales", and <sales-analytics></sales-analytics> is a component I created to render a graph with Vue-ApexCharts library. However, the graph does not render automatically when the tab is selected. It can only run after I clicked F12 on Chrome, reloading the page does not work either.

I am thinking that the component should only run after the tab has been selected, rather than run altogether when the site is loaded (as this causes render problem when the tab is not selected when the site loads). Does anyone know how to implement this? Or an alternative way to solve this issue?

More stuff from the script section:

<script>
   import Sales from '../analytics/Sales'

export default {
    components: {      
        'sales-analytics': Sales
}
</script>

EDIT: After quite a bit of Googling, I found this: https://github.com/apertureless/vue-chartjs/issues/157 Which has a very similar behaviour to my situation, I want to v-if and mounted to load the component after the tab is selected. Anyone know how to do it?

Duncan Hui
  • 247
  • 2
  • 4
  • 11
  • It's not an issue with the component being rendered at page load as much as it is an issue with Vue-ApexCharts needing to have the graph redrawn when hidden in a bootstrap tab. There's ton of instances of this with so dozens of chart libraries out there. – Ohgodwhy Oct 31 '18 at 01:52
  • Thanks for the comment. Any idea how to force the ApexCharts to redraw after the tab is selected? – Duncan Hui Oct 31 '18 at 09:35

4 Answers4

5

Thank you all of the comments. And for any future references, I was able to resolve the issue by using v-if to check the current active tab, and then load the component under the scope.

<div v-if=“activeTab === ‘sale’>
Duncan Hui
  • 247
  • 2
  • 4
  • 11
3

As per BootstrapVue docs, it is built in to load components & data only when activating a tab:

Sometimes it's preferred to load components & data only when activating a tab, instead of loading all tabs (and associated data) when rendering the set.

Individual components can be lazy loaded via the lazy prop, which when set doesn't mount the content of the until it is activated (shown), and will be un-mounted when the tab is deactivated (hidden):

<b-tab lazy>

One can also make all tab's lazy by setting the lazy prop on the parent component:

<b-tabs lazy>

Adapted to the code in the question:

<b-tab lazy title="Sales" :title-link-class="'tab-title-class'">
    <sales-analytics></sales-analytics>
</b-tab>

The downside of this solution: the lazy directive cannot be used conditionally. That means, you cannot have some tabs lazy loaded and some not IF you render them using v-for.

jasie
  • 2,192
  • 10
  • 39
  • 54
0

If you want to force ApexCharts to redraw after tab selection, you should call the refresh() method to redraw chart

<template>
  <div class="example">
    <apexcharts ref="chart" width="500" height="350" :options="chartOptions" :series="series"></apexcharts>
  </div>
</template>

<script>
  afterTabSelection: function() {
    this.$refs.chart.refresh()
  },
</script>
junedchhipa
  • 4,694
  • 1
  • 28
  • 28
-1
component: resolve => {
            require(['./component.vue'], resolve);
        },

This is loaded when it is used. May also need v-if

qihan fu
  • 7
  • 2