There are several ways to use Vue and D3 together. Here’s an attempt to use D3 for the DOM and Vue for the reactivity. I think it’s a little different from other techniques I’ve seen. I’m using no watchers and I’m using no refs. It’s based on my Vue + Canvas code.
The code is below (also here). The main idea is that there’s a reusable Vue component that produces a <g> element. You pass a function to that component to perform the one-time setup, and then return a function that should be called on update.
Look at the draw(parent). It’s d3 code. It doesn’t do any Vue-specific things. In theory, this will make it easier for you to reuse this code in another project that doesn’t use Vue.
Motivation: I try to avoid watchers. There are two errors I make:
(correctness) As I change the code, I might introduce a dependency that I forgot to watch. I change that value but the diagram doesn’t update, even though it should.
(performance) As I change the code, I might no longer have a dependency that I have been watching. I change that value and the diagram updates, even though it shouldn’t.
By using Vue’s automatic dependency tracking, these dependencies are always accurate, and I avoid both of these issues.
Caveats: the code assumes that the element is created only once. This is probably fine for most cases, but you can’t turn it on and off with v-if, or add a variable number of them with v-for, etc. Maybe :key would help; I’m not sure.
I haven’t used this in a real project and there may be more caveats.