首页 > 解决方案 > 无法将 d3 集成到 Vue 3 组件中

问题描述

我已经在项目目录d3中安装了依赖项,如下所示:

npm install d3 --save

我已经像这样导入了d3模块Component

import d3 from "d3";

这对我没有任何错误或警告。不幸的是,从d3模块调用任何方法都会失败。

例如,我尝试绘制select折线图,但模块的第一个方法出现错误。

Uncaught (in promise) TypeError: Cannot read property 'select' of undefined.

这怎么可能?d3将鼠标悬停在模块的每个方法上都会VS Code向我显示该方法的文档。所以我猜这个模块不能是未定义的。

<script>
import d3 from 'd3';
const data = [99, 71, 78, 25, 36, 92];
export default {
  name: 'non-vue-line-chart',
  template: '<div></div>',
  mounted() {
    const svg = d3.select(this.$el) // the error appears on the very first line of the d3-module
      .append('svg')
      .attr('width', 500)
      .attr('height', 270)
      .append('g')
      .attr('transform', 'translate(0, 10)');
    const x = d3.scaleLinear().range([0, 430]);
    const y = d3.scaleLinear().range([210, 0]);
    d3.axisLeft().scale(x);
    d3.axisTop().scale(y);
    x.domain(d3.extent(data, (d, i) => i));
    y.domain([0, d3.max(data, d => d)]);
    const createPath = d3.line()
      .x((d, i) => x(i))
      .y(d => y(d));
    svg.append('path').attr('d', createPath(data));
  },
};
</script>

一定有一些集成不匹配,我自己无法修复。请帮忙。

标签: javascriptd3.jsvuejs3

解决方案


知道您使用的是哪个版本的 d3 会很有帮助。我将假设它是最新的,此时是 v6。

d3 v4 仍然使用import d3 from 'd3';导入方式,但在 v6(和 v5)中,现在使用 ES 模块并且方式是。

import * as d3 from 'd3';

此更改允许开发人员选择他们需要的功能,然后编译器可以对依赖项进行树摇动并仅包含所需的功能。

所以你也可以这样做:

import {select, scaleLinear, axisLeft, axisTop, extent, max, line} as d3 from 'd3';

最后得到一个更小的捆绑包


更新

错误:Uncaught (in promise) DOMException: Failed to execute 'appendChild' on 'Node': This node type does not support this method.告诉你$elind3.select(this.$el)不是节点。要解决此问题,请使用 insidethis.$nextTick(function () {...})

文档

mounted

类型:功能

**细节: **

在挂载实例后调用,其中传递给 app.mount 的元素被新创建的 vm.$el 替换。如果根实例挂载到文档内元素,则调用 mount 时 vm.$el 也将在文档内。

请注意,mounted 并不能保证所有子组件也已安装。如果你想等到整个视图被渲染,你可以在mounted里面使用vm.$nextTick:

mounted() {
  this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been rendered
  })
}

推荐阅读