Vue.js - 反应性组件,并不总是重新渲染

时间:2017-05-19 17:18:38

标签: javascript charts vue.js vuejs2

我遇到了两个组件line-chartbar-chart

的反应问题

当我将复选框值链接更改为v-model="formChart.type时,组件line-chartbar-chart会自动重新呈现。

当我点击触发功能button然后submitFormgenerateChart() resetTypeChart()的{​​{1}}时,

但是渲染的。

未触发mounted()功能。

我真的不明白为什么会发生这种情况,因为我正在重置typeshow ....我尝试使用或不使用Vue.set没有任何改变。

代码会进入resetTypeChart()函数

组件并不总是重新渲染

  <div class="chart-container">
      <line-chart v-if="formChart.type === 'line_chart' && formChart.show" :chartData="dataChart" ref="lineChart"></line-chart>
      <bar-chart v-if="formChart.type === 'bar_chart' && formChart.show" :chartData="dataChart" ref="barChart"></bar-chart>
  </div>

复选框以更改图表类型

<el-radio-group size="small" v-model="formChart.type">
     <el-radio-button label="line_chart"> Line Chart </el-radio-button>
     <el-radio-button label="bar_chart"> Bar Chart </el-radio-button>
</el-radio-group>

生成图表的按钮

<el-button type="primary" size="large"@click="submitForm('formChart')">Generate</el-button>

submitForm(formName) {
   this.$refs[formName].validate((valid) => {
      this.generateChart();
      this.resetTypeChart();
   } 
});

重置图表的功能(尝试一下)

resetTypeChart () {
  const saveType = this.formChart.type;
  this.formChart.type = '';
  this.formChart.show = false;
  Vue.set(this.formChart, 'type', saveType);
  this.formChart.type = saveType;
  this.formChart.show = true;
 }

的jsfiddle

  • 切换到Bar Chart并生成组件
  • 点击Generate,同时仍在同一个单选按钮上。没有显示任何内容。

https://jsfiddle.net/rd3ahxp8/3/

1 个答案:

答案 0 :(得分:1)

单击“生成”按钮时没有看到警报的原因是因为Vue已确定没有任何内容真正发生更改,因此不需要更新DOM。正如我在上面的评论中所说,Vue DOM更新是异步发生的,这意味着Vue不会检查是否有任何更改,直到 方法完成之后。当您的方法完成时,您所在州的任何内容都没有真正改变;您将其设置为某个值,然后将其设置回原始值。

要演示I modified your fiddle并在清除值和设置值之间引入时间延迟。您可以看到,在情况下,Vue有时间检查值是否已更改,然后更改返回,您会收到消息。

generateChart : function () {
    alert('generate')
    const saveType = this.formChart.type;
    this.formChart.type = '';
    this.formChart.show = false;
    setTimeout(()=>{
        this.formChart.type = saveType;
      this.formChart.show = true;

    }, 1000)
}

我认为在您的案例中触发更新是对dataChart的一些更改。当该值发生变化时,您的Vue 重新渲染。但是,您没有表明它会发生变化。现在,如果数据没有改变,并且您不希望用户看到不同的图表(因为您将其设置回相同的值),为什么要重新渲染所有?

为了让图表在chartData更改时重新渲染,您应该在组件中查看chartData属性。以下是我如何做到这一点的完整示例。

const ChartBase = {
  props: ["chartData"],
  methods:{
    showChart(){
      this.renderChart({
        labels: this.chartData.labels,
        datasets: [
          {
            label: 'Data One',
            backgroundColor: '#f87979',
            data: this.chartData.data
          }
        ]
      }, {responsive: true, maintainAspectRatio: false})
    }
  },
  mounted : function () {
    this.showChart()
    this.$watch("chartData.data", this.showChart)
  },
}

Vue.component('bar-chart', {
  extends: VueChartJs.Bar,
  mixins: [ChartBase]
});

Vue.component('line-chart', {
  extends: VueChartJs.Line,
  mixins:[ChartBase]
});

var Main = {
  data () {
    return {
      formChart : {
        type : 'line_chart',
        show : false,
      },
      chartData:{
        labels:['January', 'February', 'March', 'April', 'May', 'June', 'July'],
        data: [40, 39, 10, 40, 39, 80, 40]
      }
    };
  },
  methods : {
    generateChart : function () {
      const newChartData = [...this.chartData.data.reverse()] 
      this.chartData.data = newChartData
    }
  },
}

here is a fiddle显示单击generate按钮时图表的更改。