为什么我必须在使用ChartJS之前创建我的VueJS应用程序?

k4aesqcs  于 2022-11-06  发布在  Chart.js
关注(0)|答案(1)|浏览(207)

我有一个非常简单的页面,它可以正常工作:

<!DOCTYPE html>
<html lang="en">

<head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js@3.7.0/dist/chart.js"></script>
</head>

<body>
    <main id="vue-app">
        <p>{{ name }}</p>
        <canvas id="chart-flow-rate"></canvas>
    </main>
</body>

<script>    
    // Start VueJS
    const Application = {
        data() {
            return {
                name: "My Chart"
            };
        }
    }
    vm = Vue.createApp(Application).mount('#vue-app');

    // Use ChartJS
    const myChart = new Chart('chart-flow-rate', {
        type: 'bar',
        data: {
            labels: ['4', '2'],
            datasets: [{
                data: [4, 2],
            }]
        }
    });
</script>

但是,如果我反转JS的块以使用ChartJS firstthen 来创建VueJS应用程序,则该页面将不再工作:该图未示出。
"为什么"
我注意到我可以稍微修改一下HTML的body,以便能够在VueJS之前使用ChartJS:

<body>
    <main>
        <p id="vue-app">{{ name }}</p>
        <canvas id="chart-flow-rate"></canvas>
    </main>
</body>

又:为什么
非常感谢!:)

91zkwejq

91zkwejq1#

这是因为VueJS使用虚拟DOM,并且它成批更新实际的DOM:您提供给应用的是内联模板,VueJS将解析、插入并将其重写为DOM。因此,如果您首先初始化ChartJS,它将丢失对DOM元素的引用(它要么因为与VueJS的争用条件而消失,要么在Vue计算虚拟DOM并将其输出到实际DOM后被Vue快速覆盖)。
更改标记之所以有效,是因为ChartJS用于装载和呈现图表的元素现在不再被VueJS擦除或操作,因为它不再是Vue应用程序的一部分,而是驻留在它之外的常规DOM中。
事实上,最节省的解决方案是在VueJS应用的mounted钩子中示例化ChartJS,并在等待DOM准备就绪后,即:

mounted: async function() {
    // Wait for the DOM to be rendered after next tick
    await this.$nextTick();

    // Use ChartJS with the element that now exists in the DOM
    const myChart = new Chart('chart-flow-rate', {
        type: 'bar',
        data: {
            labels: ['4', '2'],
            datasets: [{
                data: [4, 2],
            }]
        }
    });
}

实际上,我会更进一步,恳求您避免使用DOM查询方法,并利用ref属性和$refs示例属性。

<canvas ref="chart"></canvas>

由于ChartJS接受一个元素作为第一个参数,因此只需使用this.$refs.canvas访问该元素:

const myChart = new Chart(this.$refs.chart, { ... })

请参阅下面的概念验证:
第一个

相关问题