Menu
Dev Bay – front-end tips
  • Front-end tips
  • Back-end tips
  • Converters
Dev Bay – front-end tips

Popover on hover in VueJS

Posted on February 4, 2022April 9, 2022

Hi! I will create in this short tutorial a popover (sometimes named as tooltip) component in VueJS. I didn’t use in my example any third-party library, like Bootstrap or Vue Bootstrap. This is a pure tooltip/popover component in VueJS just with JavaScript usage.

Why it is better to create your own popover in VueJS than use external library for that? For me the best explanation is that we have then full control over the created solution and we can easily adapt or modify it when need. And this can be problematic in external solutions.

Table of Contents

  • Popover on hover over in VueJS – short solution with explanation
    • 1 – Main application App.vue file – default starting point of Vue CLI app
    • 2 – Popover.vue file – component with basic popover
  • VueJS popover – summary
  • VueJS popover – code
    • Related posts:

Popover on hover over in VueJS – short solution with explanation

I will add here screen shots of my solution of Popover in VueJS code, and next I will focus deeply on each important part.

My very basic popover app in VueJS you can find here:

  • Live demo – open here
  • Github code – open here
  • App in frame below:

I created in my VueJS popover/tooltip example in Vue CLI to make it easy and straightforward. I have there 2 key files:

1 – Main application App.vue file – default starting point of Vue CLI app

Code in textual format is at the bottom of this article.

VueJS popover/tooltip - parent component
VueJS popover/tooltip – parent component

Lets have here a closer look for code above. This is the hosting or parent component code. Let’s check it closer:

  1. We must normally import here a VueJS Popover component by import statement and put that component into HTML code.
  2. Key part here is to add a reference ref="popover", which we use in Vue lifecycle hook – updated. In updated hook we must trigger Popover’s init method always when parent (hosting) vue component is updated.
    Why? Because when parent component is updated, than new elements requiring popover might appear there. So popover component must check all HTML elements for data-popover property and reinitialize itself for them.
  3. There is also a v-for loop and button to generate new links with – to show how reinitializing of vuejs popover goes.

2 – Popover.vue file – component with basic popover

Code in textual format is at the bottom of this article.

VueJS popover/tooltip - key code
VueJS popover/tooltip – key code

This is the key component with popover. Let’s check its most important parts:

Long story short – VueJS popover/tooltip components checks for all elements in parten component which has “data-popover” HTML attribute and assign to it mouse move event to show then a popover.

  1. First in HTML part we have short HTML code, where show variable switches visibility of popover and positionInlineStyle computed property sets right position of popover according mouse cursor position over the HTML element with popover.
  2. Key method is init. Here we have pure JavaScript code. It is looking for all HTML elements in parent (hosting) component which has data-popover attribute and next assign to each mousemove event with  setPopoverData method which defines position and visibility for vuejs popover initialized at moment (when mouse cursor move over the HTML element).
  3. On the beginning of init method all previously created events are removed.
  4. At the end the proper CSS styles are applied to show popover/tooltip in a right position and layer.

We can say that whole popover component is based on a JavaScript closer – because data (html/css/vuejs) is used on fly on binded move move event.

VueJS popover – summary

This short example of VueJS popover shows how we can easly create and use our own component to display important information to the user on fly, like a native title HTML attribute. THis can be done in many ways, here I showed option based on native JavaScript DOM elements, attributes and mouse events together with VueJS component.

VueJS popover – code

  1. Parent (hosting) VueJS component code:
    <template>
      <div id="app">
        
        <popover ref="popover" />
    
        <a href="https://dev-bay.com" data-popover="This is a popover from Dev-Bay.com!">Link to Dev-Bay.com</a>
    
        <div class="more">
          <div v-for="(i, k) in q" :key="k">
            <a href="https://dev-bay.com" :data-popover="'This is a new link with popover' + i">New link {{i}}</a>
          </div>
          <button @click="addLinks">Add more links</button>
        </div>
    
      </div>
    </template>
    
    <script>
    import Popover from './components/popover.vue'
    
    export default {
      name: 'App',
      components: {
        Popover
      },
      data () {
        return {
          q: 0,
        }
      },
      methods: {
        addLinks () {
          this.q += 10;
        }
      },
      updated () {
        this.$refs.popover.init();
      }
    }
    </script>
    
    <style>
    #app {
      width: 500px;
      margin: 20px auto;
    }
    .more, button {
      margin-top: 20px;
    }
    </style>
    
  2. Popover VueJS component code:
    <template>
      <div v-show="show" class="popover" :style="positionInlineStyle">
        {{txt}}
      </div>
    </template>
    
    <script>
    export default {
      name: 'HelloWorld',
      data () {
        return {
          show: false,
          txt: '',
          posX: 0,
          posY: 0,
          popovers: []
        }
      },
      methods: {
        init () {
          this.removeListeners();
          this.popovers = this.$parent.$el.querySelectorAll('[data-popover]');
          
          this.popovers.forEach(popover => {
            popover.addEventListener("mousemove", this.setPopoverData);
            popover.addEventListener("mouseleave", this.clearData);
          });
          
        },
        removeListeners () {
          this.popovers.forEach(popover => {
            popover.removeEventListener("mousemove", this.setPopoverData);
            popover.removeEventListener("mouseleave", this.clearData);
          });
          this.popovers = [];
        },
        setPopoverData (e) {
          this.show = true;
          this.txt = e.target.getAttribute('data-popover');
          this.posX = e.x - 10;
          this.posY = e.y + 30;
        },
        clearData () {
          this.show = false;
          this.txt = '';
          this.posX = 0;
          this.posY = 0;
        }
      },
      computed: {
        positionInlineStyle () {
          return `left: ${this.posX}px; top: ${this.posY}px`;
        }
      },
      mounted () {
        console.log('mounted');
        this.init();
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
      .popover {
        background: #fff;
        border: 1px solid #ccc;
        border-radius: 5px;
        position: absolute;
        padding: 10px;
        z-index: 9999;
      }
      .popover::before {
        content: '';
        width: 0;
        height: 0;
        border-left: 5px solid transparent;
        border-right: 5px solid transparent;
        border-bottom: 5px solid #ccc;
        position: absolute;
        top: 0;
        left: 10px;
        transform: translateY(-100%);
        z-index: 9999;
      }
      
    
    </style>
  3. You can check that also here:
    Live demo – open here
    Github code – open here

Related posts:

Insert JavaScript vuejs/react/angular apps into SalesForce page Send data between SalesForce and JavaScript Vue/React/Angular app in Aura component Create modal window in vanilla JavaScript
©2023 Dev Bay – front-end tips | Powered by SuperbThemes & WordPress