如何在Vue.js方法中捕获SVG元素的悬停事件,并将原生JavaScript悬停事件与Vue方法组合使用。

4

我之前开发了一个vuejs + d3.js + jit库的项目。 现在,我需要为d3.js的svg元素添加悬停功能,以显示鼠标悬停元素的信息弹出对话框。 我尝试多次按照一些stackoverflow的指示进行操作。 但它们都不适用于我的项目。 以下是我的代码片段。

allNodes.append("circle").attr("@mouseover", "console.log('test');");
allNodes.append("circle").attr(":v-on:mouseover", "console.log('dfdfd');");

上面的代码无法正常工作,因为当Vue组件挂载时,d3.js元素被渲染,而Vue模板解析器无法编译v-on、@mouseover属性。但是下面的代码可以正常工作。
allNodes.append("circle").attr("onmouseover", "console.log('test');");

我认为我可以将本地JavaScript函数附加到Vue方法以显示弹出对话框。
但是,我不确定如何配置所有项目结构以及在项目中放置本地功能的位置。
请帮帮我。
谢谢。
1个回答

5
你可以在d3选择器上使用.on("mouseover", this.vueMethod),其中this.vueMethod在Vue组件的methods对象中定义。

new Vue({
  el: "#app",
  data: {
    todos: [
      { text: "Learn JavaScript", done: false },
      { text: "Learn Vue", done: false },
      { text: "Play around in JSFiddle", done: true },
      { text: "Build something awesome", done: true }
    ],
    todoHovered: "hover a circle"
  },
  mounted() {
    const svg = d3.select(this.$refs.chart)
      .append("svg")
        .attr("width", 400)
        .attr("height", 100);
    const circles = svg.selectAll("circle")
      .data(this.todos).enter()
      .append("circle")
        .attr("cx", 10)
        .attr("cy", (d,i) => 10 + i * 15)
        .attr("r", 5)
        .style("fill", d => d.done ? "green" : "red");
    circles.on("mouseover", this.showMessage);
    circles.on("mouseout", (e) => d3.select(e.currentTarget).attr("r", 5));
  },
  methods: {
    showMessage(e, d) {
      d3.select(e.currentTarget).attr("r", 8);
      this.todoHovered = `${d.text} is ${d.done ? 'done' : 'not done'}`;
    }
  }
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}
<script src="https://d3js.org/d3.v6.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>

<div id="app">
  <div ref="chart">
  </div>
  <p>
    Message: {{ todoHovered }}
  </p>
</div>


2
从版本v6.0.0开始,d3在selection.on的第一个参数中使用事件本身。我已经编辑了答案以反映这个变化:showMessage(d) {...} 变成 showMessage(e, d) {...} - thibautg
只是一个快速的问题@thibautg,如果我想要扩大悬停的圆的半径,我该怎么做? - djcaesar9114
1
我已经编辑了答案,将圆的半径在鼠标悬停时更改为8(在showMessage方法内)。我添加了另一个事件,在鼠标移出时将其设置回5。 - thibautg
1
非常感谢,您在短短几分钟内的解释比我在网上看到的很多教程都要好。 - djcaesar9114
@djcaesar9114 谢谢,不用谢,你让我今天过得很愉快! - thibautg
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接