[Vuejs]-Vue.js dynamic changes to DOM by external library (jQuery style)

1👍

Vue Custom Directives can be a best solution for you in tackling this issue.Basically Directives are tiny commands that you can attach to DOM elements.They are typically useful if you need low-level access to an HTML element to control a bit of behavior. Add whatever styling or behavior you want in this directive and use wherever you want it.

Steps for Creating Custom Directives.

For example you want to make a directive for a background, let say name it CustomBackgroundDirective then first create a new file called CustomBackgroundDirective.js like.

import Vue from 'vue';

const defaultBackgroundColor = '#86bbff'

// Initialize the custom-background directive.
export const CustomBackground = {
  bind(el, binding, vnode) {
    // Allow users to customise the color by passing an expression.
    const color = binding.expression || defaultBackgroundColor

    // el might not be present for server-side rendering.
    if (el) {
      // Set the element's background color.
      el.style.backgroundColor = color
    }
  }
}

// You can also make it available globally.
Vue.directive('custom-background', CustomBackground)


Now to use it in a component, simply add it to your component template prefixed with a v- like

<template>
  <div>
    <p v-custom-background>Baby blue looks good on me.</p>
    <p v-custom-background="#0f0">I prefer neon green.</p>
  </div>
</template>

<script>
import { CustomBackground } from './CustomBackgroundDirective.js';

export default {
  directives: {
    CustomBackground
  }
}
</script>


Moreover there are a few hooks available to the directive with which you can play, and each one has the option of a few arguments. The hooks are as follows:

  • bind – This occurs once the directive is attached to the element.
  • inserted – This hook occurs once the element is inserted into the
    parent DOM.
  • update – This hook is called when the element updates, but children
    haven’t been updated yet.
  • componentUpdated – This hook is called once the component and the
    children have been updated.
  • unbind – This hook is called once the directive is removed.

2👍

In vuejs you have a feature called Directive which is a great tool for this type of situation. Just create a global directive ( because it seems that you will be using it in multiple places ) and in it add all your necessary styling and behavior you are interested in.

1👍

You cannot do what you are describing with VueJS. There’s a fundamental difference between jQuery and VueJS.

  1. jQuery manipulates the dom
  2. VueJS uses a virtual dom

A virtual dom has the same properties as real dom, but it’s must faster since its not drawing anything on the screen. It then gets compared to the real dom and updated according to what changed.

When you’re constantly manipulating the dom and redrawing the site becomes slower and keeping the state of the website gets tricky. That’s why VueJS uses components with props and events.

So, Vue makes the dom react to data changes rather than editing the html element itself.

Vue does have some limited ability to manipulate the dom directly through ref attribute, but it’s reccomended to avoid it when possible.

The ‘vue way’ is to use single file components to create your site. See: https://v2.vuejs.org/v2/guide/single-file-components.html along with mixins and directives.

That means one component for each ‘thing’ on your website, for example <MyButton> or <NavigationBar>, etc.

If everything is set up that way then you can simply change the template or the style in that single file and every <MyButton> on your website would change. You would never change it on the fly by manipulating the dom like with jquery.

Although it’s not ‘clean’ there is nothing stopping you to have vuejs and jquery together. So vuejs would use virtual dom, update the real dom and then jquery would manipulate it.

It will be hard to keep track of the state since there some ‘magic happening’ and two frameworks affecting how the website looks. e.g. some styling in vue and then jquery overriding or changing it.

1👍

I think what you want will be possible in Vue 3 thanks to it’s new modular architecture by overriding default renderer. You can find some examples in this great article

I don’t think it’s a good idea but I can imagine one should be able to create jQuery-like experience in Vue this way….

EDIT

I see your edit (added examples) and I need to add something. When I was talking about "jQuery-like experience" it was really about modifying DOM at runtime by changing how the virtual DOM is used to patch real DOM.

But all your examples are using some Vue features which are totally separate (way higher in the stack). For example adding directive or changing the prop – this has to be done on the template itself (and templates are compiled into render functions at build-time) or by replacing default createElement (usually called h) function, which is imported globally in Vue 3 so I’m not sure if its possible to replace it…

This is something really different and way way more difficult…

0👍

You can just use modern CSS:
https://css-tricks.com/css-content/#example-trick-css3-tooltips

If that doesn’t meet your needs, the next most simple thing to do would be to make a Component that has the visuals you want and then add it where necessary.

Vue is controlling the rendering of the DOM, so it’s not going to work like jQuery which parses the DOM and then injects its own elements. If you really wanted to go crazy with it, you should be able to create a global mixin in Vue with a render function and a custom merge strategy that injects the mixin tooltips based on the inspection of the rendered component. I’m not sure I would call that "the Vue way" though.

0👍

Been building apps and sites with Vue since 2015, before that I was a heavy jQuery user for years. After reviewing other answers and your responses I don’t believe the answer you seek is actually related to Vue.

My first thought was "directives" like others had mentioned.

It appears you want the sugary-syntax you once had with jQuery for selecting DOM elements and applying changes in a chain-like fashion; this can be done with vanilla JavaScript. The challenge you face is working within Vue and waiting for components to finish rendering before attempting to select all possible DOM nodes. There are tricks for this, like using $nextTick() to wait for child components to finish rendering before attempting to select all the possible DOM nodes.

I can say I no longer need or want to use jQuery, and have yet to run into a use-case where I needed anything like $('a[title]').each(function(){ ... add styling, new nodes, etc... }).

If you could share more information about what it is you are trying to achieve people could likely give a more distinct answer. I do believe that there is a simple solution here, but without knowing more about your challenge it’s hard to answer.

0👍

You don’t need Vue, JavaScript or jQuery!

A tooltip can be accomplished with pure HTML/CSS.

I know this doesn’t solve all your other examples. However, because a lot developers reach for JavaScript when it might not alway be necessary, I think this answer could be helpful for others.

[data-title]:hover::after {
  content: attr(data-title);
}
<p data-title="title">Hover me </p>

For a more detailed explanation see:

-1👍

There is Vuetify, if that’s helping you out. I would do this with CSS or even LESS, look at how a title is represented in the HTML generated. If it’s an attribute called v-title, for example, then a CSS rule of

[v-title] {
    /*Your rules here*/
}

will apply to elements having that attribute. You could vary it, for example

h1[v-title] {
    /*Your rules here*/
}

would apply to h1 elements having that attribute. Or,

div > [v-title] {
    /*Your rules here*/
}

would apply to any elements having that attribute, as long as their parent is a div. But, if you want a third-party design, then you can find this one, for example: https://vuetifyjs.com/en/components/subheaders/

I would advise you though to implement your own design unless you are forced not to do so, because customizing third-party designs have their limitations.

Leave a comment