Dec 4, 2019

How to use Vue.js on jQuery legacy websites

jQuery Vue.js

One of the reasons it was very hard for me to start using Vue is because I was coding on existing websites whose frontend was built with jQuery.

jQuery? Yes, jQuery.

Before getting used to vue, I was constantly choosing jQuery for new projects, because I was quite familiar with it. This made me very fast at launching apps with laravel, since blade is enough to create an MVP.

But, as soon as the projects started growing, more complex functionality was required. For me this was the moment to realize jQuery was not enough, especially when I wanted to provide the perfect experience to my website's users.

So I wanted to start using Vue.js but the challenge was that vue dominates the dom it uses. And when vue is there, it doesn't give any air for jQuery to breathe.

Luckily though, after searching around on the web with my co-founder, we found a solution on how to use Vue into projects with jQuery. My goal is to share this know-how with you.

One of the things that made it very hard for me to understand how to couple Vue.js with jQuery was the fact that vue lives in what we all know as a root component and I call a "silo".

What tutorials teach

If you have your whole html code wrapped inside a single root component, then you have a big big silo belonging to Vue.js. I know, this is what tutorials teach. But if this how you attempt to "inject" Vue.js into a jQuery project, that cannot and will not work.

But I love root components! I hear you say. Patience friend, we will get there.

One characteristic of Vue.js is it absorbs all the window events. Something like a black hole. This means that jQuery's on.('click') wouldn't work inside a vue component. Your top navigation and hamburger menu code coded with jQuery would stop work for instance.

Then, (Hallelujah music in the background) we realized we could have multiple Vue.js root components into a page. By doing that we could limit the scope of anti-social but so beautiful Vue.js components into smaller black-hole-component-silos.

So instead of having one huge root component-silo belonging to Vue.js, we had to inject multiple mini ones we could use here and there. And as long as these did not interact in some way with jQuery, happy life could go on.

Enough with the theory and the sentimental talk. Let's see some code.

The code

On our passion project metabook.gr (don't open the link, unless you speak greek), we wanted to lazy load the book covers.

You clicked the link nevertheless, didn't you?

Anyway, this is the html code of our vue component:

<lazy-img class="vue-root" src="/image.jpg">

Of course that won't work unless we tell javascript to load it as a vue component.

In our app.js we declare that every element with the class ".vue-root" is a vue root component.

import LazyImg from './vue/lazy-img' const vueRootElements = document.querySelectorAll(".vue-root"); Array.prototype.forEach.call(vueRootElements, (el) => new Vue({el, components: { ImgLazy }}))

By using the trick above, we were finally able to insert Vue.js components anywhere we like without worrying too much. Also, any new javascript code can now be written with Vue.js and slowly replace jQuery with Vue.js!

And this makes us happy because Vue.js is much more fun to work with!

Thank you for reading this!

If you use a different approach, please do share it with me!