-1

 I'm creating an app using Nodejs and Vuejs 3. In this app I have made a sidebar that gets all links from a routes file and present them. This sidebar consists in a component that parents a list of other recursive link components.

 Since the links are recursive and many, I find it hard to deal with class toggling (active, showing, collapsed, etc.) on each of them and relate them to one another (if one is active the others shouldn't be) using only Vue. Should I use querySelector or any frameworks such as JQuery to handle them or should I try to stick with a pure Vuejs approach?

Edit:

 I don't want to gather the community's opinion on it. My aim is to understand pragmatically why I should or shouldn't manipulate the DOM "outside" of Vue.

Giovanni Di Toro
  • 797
  • 1
  • 14
  • 34
  • stick to one framework – depperm Oct 19 '21 at 14:11
  • 1
    see class binding question that might help: https://stackoverflow.com/q/33731939/3462319 – depperm Oct 19 '21 at 14:13
  • Adding to @DanielBeck's comment, Vue internally uses a ShadowDOM thus everything you do with jQuery is not reflected there and probably gets lost when Vue re-renders a component. – Thomas Oct 19 '21 at 14:21
  • 2
    @Thomas You likely meant virtual DOM. – Estus Flask Oct 19 '21 at 14:24
  • Going the other way around, doing this with a framework that you currently using (Vue) should be a first choice, and there are there are not enough reasoning to consider other options (jQuery). That you're not confident enough with Vue shouldn't be considered a valid reason because it's a shortcut. This doesn't explain what exactly is wrong with doing what you want to do (but it's wrong for several reasons) but provides a reasonable point of view at this decision. – Estus Flask Oct 19 '21 at 14:32
  • @EstusFlask true, Virtual DOM is the right word – Thomas Oct 20 '21 at 06:06

1 Answers1

2

If you're using Vue then let it be in control of the DOM; mucking around directly will only create conflicts and woe.

(The same applies to other SPA frameworks such as React and Angular.)

The main reason not to touch the DOM is that Vue works by modifying the DOM on its own, and expects to have complete control over it: when rendering components the framework is removing old DOM elements, adding new ones, updating event bindings, etc; and a lot of it is optimized to only update the DOM nodes that need to be updated.

If you go in there and start making direct changes that Vue doesn't know about, then it's likely that your own changes will get overwritten by Vue the next time it needs to render, or that your changes will overwrite bindings that Vue is depending on.

If you're very knowledgeable about Vue's lifecycle and know how to control when it does and does not render, it is possible to work with both together -- but even then it's still not a great idea. Vue and jQuery do very similar things, but in utterly different ways. In jQuery you build up the page and then use DOM traversals and event handlers to modify it; everything lives inside the DOM. In Vue you build up a bunch of components that manage their own state and rendering; the DOM is basically a side effect of the application state.

By trying to use both together you lose most of the advantages of each of them in isolation, and introduce a lot of complexity in having to manage two competing theories of state and render management (not to mention dealing with communicating data between them). Every time I've contemplated embedding a jQuery widget inside a Vue app, it's turned out to be much easier to just rewrite the widget in Vue directly.

This does mean changing a lot of habits about working with the DOM that you may have built up from past jQuery work. It sounds like you're trying to draw the whole DOM and then build your control structure into it afterwards, which is a natural way to think if you're used to jQuery; in Vue you'll want to build all of that logic into components so the framework can do the work for you. I'd suggest making one Vue component for a link that manages its own state for open / closed / active etc, that recurses to its children only when "open". Then just call that once with the top of your nav data instead of trying to manage the whole tree directly after the fact as you would in jQuery.

Daniel Beck
  • 20,653
  • 5
  • 38
  • 53