You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3同一组件多次复用仅首个实例的D3功能正常问题求助

问题根源

你的代码中所有D3选择器都使用了全局标签选择select('svg')、select('svg g'),这类选择器会默认匹配整个文档中第一个符合条件的DOM节点,所以无论你实例化多少个组件,所有D3操作都会集中到第一个组件的SVG节点上,后续组件自然没有内容生成。同时你代码中svg.append("svg")属于冗余操作,template里已经声明了SVG节点,不需要重复追加。


修复后可正常复用的代码

<template>
  <div class="fill-100">
    <svg ref="svgRef" width="400" height="667">
      <g ref="gRef"></g>
    </svg>
  </div>
</template>

<script>
import { ref, onMounted } from "@vue/runtime-core";
import { select, zoom } from "d3";

export default {
  name: "SldSvgD3",
  props: ["id"],
  setup() {
    const svgRef = ref(null);
    // 直接绑定当前组件内的g节点,避免全局查询
    const gRef = ref(null);

    onMounted(() => {
      // 所有操作都限定在当前组件的节点范围内
      const currentSvg = select(svgRef.value);
      const currentG = select(gRef.value);

      let data = [], width = 400, height = 667, numPoints = 100;

      const zoom3 = zoom()
        .on('zoom', handleZoom);

      function handleZoom(e) {
        currentG.attr('transform', e.transform);
      }

      function initZoom() {
        // 仅给当前组件的SVG绑定缩放事件
        currentSvg.call(zoom3);
      }

      function updateData() {
        data = [];
        for(let i=0; i<numPoints; i++) {
          data.push({
            id: i,
            x: Math.random() * width,
            y: Math.random() * height
          });
        }
      }

      function update() {
        // 仅在当前组件的g节点下生成圆点
        currentG
          .selectAll('circle')
          .data(data)
          .join('circle')
          .attr('cx', d => d.x)
          .attr('cy', d => d.y)
          .attr('r', 3);
      }

      initZoom();
      updateData();
      update();
    });

    return { svgRef, gRef }
  }
}
</script>

<style lang="scss">
.fill-100{
  width: 100%;
  height: 100%;
}
</style>

核心修改说明

  • 新增gRef直接绑定当前组件内的g节点,所有DOM操作都限定在当前组件的节点范围内,不会跨实例影响其他组件
  • 删除冗余的svg.append("svg")操作
  • 缩放事件仅绑定到当前组件的SVG节点,不会和其他实例的缩放逻辑冲突

内容的提问来源于stack exchange,提问作者patrpok

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 01:48:01