2016-07-24 72 views
0

我有一個簡單的應用程序,它使用Bootstrap,vue.js和chart.js。 HTML模板非常簡單。我注意到在搜索我的錯誤時,這個問題通常是在試圖在選項卡或模式中呈現圖表時引起的,但我沒有在模式或選項卡中顯示圖表。Chart.js不會渲染使用vue.js直到調整窗口

只要我調整我的瀏覽器窗口的大小,圖表就會正確呈現並縮放以適應div和所有內容。

無論出於何種原因,當第一次加載頁面,畫布HTML標記呈現這樣的:

<canvas id="graph" width="0" height="0" style="margin: auto; width: 0px; display: block; height: 0px;"></canvas> 

但是當我調整窗口的大小,一切都變了,我正確地看到圖表。

<canvas id="graph" width="493" height="328" style="margin: auto; width: 493px; display: block; height: 328px;"></canvas> 

爲什麼沒有得到它的高度在頁面加載&寬度是否正確?

HTML模板

<div class="panel panel-default"> 
     <div class="panel-heading">Chart List</div> 
     <div class="panel-body"> 
     <div class="row"> 
      <div class="col-sm-6"> 
       <defaultchart> 
       </defaultchart> 
      </div> 
      <div class="col-sm-6"> 
       <chartlistview 
        :data="{{ $private }}" 
        :columns="{{ json_encode($columns) }}" 
       > 
       </chartlistview> 
      </div> 
     </div> 
      </div> 
    </div> 

DefaultChart.vue

<template> 
    <div> 
    <canvas 
     id="graph" 
     v-el:canvas 
     width="600" 
     height="400" 
     style="margin:auto; width: 600px;" 
    ></canvas> 
    </div> 
</template> 

<script> 
    export default { 

    data() { 
     return { 
     ourChart: '', 
     chartData: { 
      labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"], 
      datasets: [{ 
      label: '# of Votes', 
      data: [12, 19, 3, 5, 2, 3] 
      }] 
     } 
     }; 
    }, 

    ready() { 

     this.drawChart();  
    }, 

    methods: { 

     drawChart: function() { 

     if (this.ourChart) { 
      this.ourChart.destroy(); 
     } 
     var context = document.querySelector('#graph').getContext('2d'); 
     this.ourChart = new Chart(context, { 
      type: 'line', 
      data: this.chartData 
      // wouldn't render at all with this regardless of resizing 
      /*options: { 
      response: true, 
      maintainAspectRatio: false 
      }*/ 
     }); 

     // added these lines to see if it would fix the issue; it didn't 
     this.ourChart.render(); 
     this.ourChart.update(); 
     } 

    } 
    }; 
</script> 

回答

3

訪問DOM中ready()是棘手的,因爲Vue的更新DOM異步,所以變化可能尚未完全應用,和/或瀏覽器尚未完成新的佈局。

使用$nextTick()推遲,直到更新已經完成:

ready() { 
    this.$nextTick(function() { 
    this.drawChart();  
    }) 
}, 

通常的伎倆在這些情況下,至少在事物的Vue公司的一面。不能多說關於chart.js配置。

+0

哇,工作。謝謝!雖然問題。這是Vue中的錯誤嗎?我認爲'ready()'方法就像在jQuery中一樣工作。還是我使用錯了,我應該總是使用'$ nextTick'? – Nathan

+1

不,這不是Vue中的錯誤。正如我所說,由於性能原因,Vue [異步更新DOM](http://vuejs.org/guide/reactivity.html#Async-Update-Queue),這意味着當Vue說「將此元素放入DOM中」 ,並在之後觸發ready()鉤子,「此元素」可能不在DOM中。 由於這是人們似乎遇到的最常見的陷阱之一,我會建議將其添加到文檔更突出。 –

+0

好吧,這是有道理的。我是在假設Vue正在監聽DOM實際準備好時從瀏覽器進行事件回調的假設下運行的。 – Nathan