DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Mocking Dependencies and AI Is the Next Frontier in Vue.js Testing
  • Serving a Vue.js Application With a Go Backend
  • Build Full-Stack Web App With Firebase, Angular 15, React.js, Vue.js, and Blazor [Video]
  • React, Angular, and Vue.js: What’s the Technical Difference?

Trending

  • How to Convert XLS to XLSX in Java
  • Ethical AI in Agile
  • AI's Dilemma: When to Retrain and When to Unlearn?
  • A Deep Dive Into Firmware Over the Air for IoT Devices
  1. DZone
  2. Coding
  3. Frameworks
  4. How to (Safely) Use a jQuery Plugin With Vue.js

How to (Safely) Use a jQuery Plugin With Vue.js

While Vue developers may cringe at the thought, sometimes it's necessary to use jQuery with your Vue.js app. Learn how here!

By 
Anthony Gore user avatar
Anthony Gore
DZone Core CORE ·
Updated Feb. 04, 20 · Tutorial
Likes (9)
Comment
Save
Tweet
Share
26.5K Views

Join the DZone community and get the full member experience.

Join For Free

It's not a great idea to use jQuery and Vue.js in the same UI. Don't do it if you can avoid it.

But you're probably reading this not because you want to use jQuery and Vue together, but because you have to. Perhaps a client is insisting on using a particular jQuery plugin that you won't have time to rewrite for Vue.

If you're careful about how you do it, you can use jQuery and Vue together safely. In this article, I'm going to demonstrate how to add the jQuery UI Datepicker plugin to a Vue project.

And just to show off a bit, I'm even going to send data between this jQuery plugin and Vue!

See it working in this JS Bin.

JQuery UI datepicker

jQuery UI Datepicker

The Problem With Using jQuery and Vue Together

Why is doing this potentially hazardous?

Vue is a jealous library in the sense that you must let it completely own the patch of DOM that you give it (defined by what you pass to el). If jQuery makes a change to an element that Vue is managing, say, adds a class to something, Vue won't be aware of the change and is going to go right ahead and overwrite it in the next update cycle.

Solution: Use a Component as a Wrapper

Knowing that Vue and jQuery are never going to share part of the DOM, we have to tell Vue to cordon off an area and give it over to jQuery.

Using a component to wrap a jQuery plugin seems like the way to go because:

  • We can utilize lifecycle hooks for setup and teardown of the jQuery code.
  • We can use the component interface to communicate with the rest of the Vue app via props and events.
  • Components can opt-out of updates with v-once

Set-Up jQuery UI Datepicker

Obviously, you need to include both the jQuery and jQuery UI libraries in your project first. Once you have those, the datepicker just requires an input element to attach itself to:

JavaScript




x


 
1
Date: <input id="datepicker"/>



It can then be instantiated by selecting it and calling the method:

JavaScript




xxxxxxxxxx
1


 
1
$('#datepicker').datepicker();



Datepicker Component

To make our datepicker component, the template will be this one input element:

JavaScript




xxxxxxxxxx
1
10


 
1
Vue.component('date-picker', function() {
2
  template: '<input/>'
3
});
4

          
5
new Vue({
6
  el: '#app'
7
});
8

          
9
<div id="app">
10
  Date: <date-picker></date-picker>
11
</div>


Note: This component should be nothing more than a wrapper for the plugin. Don't push your luck and give it any data properties or use directives or slots.

Instantiating the Widget

Rather than giving our input an ID and selecting it, we can use this.$el, as every component can access its own root node like that. The root node will, of course, be the input.

We can then wrap the node reference in a jQuery selector to access the datepicker method, i.e. $(this.$el).datepicker().

Note that we use the mounted lifecycle hook as this.$el is undefined until the component is mounted.

JavaScript




xxxxxxxxxx
1


 
1
Vue.component('date-picker', function() {
2
  template: '<input/>',
3
  mounted: function() {
4
    $(this.$el).datepicker();
5
  }
6
});



Teardown

To teardown the datepicker we can follow a similar approach and use a lifecycle hook. Note that we must use beforeDestroy to ensure our input is still in the DOM and thus can be selected (it's undefined in the destroy hook).

JavaScript




xxxxxxxxxx
1


 
1
Vue.component('date-picker', {
2
  template: '<input/>',
3
  mounted: function() {
4
    $(this.$el).datepicker();
5
  },
6
  beforeDestroy: function() {
7
    $(this.$el).datepicker('hide').datepicker('destroy');
8
  }
9
});



Pass Config With Props

To make our component reusable, it would be nice to allow for custom configuration, like specifying the date format with the configuration property dateFormat. We can do this with props:

JavaScript




xxxxxxxxxx
1
13


 
1
Vue.component('date-picker', {
2
  template: '<input/>',
3
  props: [ 'dateFormat' ],
4
  mounted: function() {
5
    $(this.$el).datepicker({
6
      dateFormat: this.dateFormat
7
    });
8
  },
9
  beforeDestroy: function() { ... }
10
});
11

          
12
<div id="app">
13
  <date-picker date-format="yy-mm-dd"></date-picker>
14
</div>



Letting jQuery Handle Updates

Let's say that, rather than passing your dateFormat prop as a string, you made it a data property of your root instance, i.e.:

JavaScript




xxxxxxxxxx
1
10


 
1
var vm = new Vue({
2
  data: {
3
    ...
4
    dateFormat: 'yy-mm-dd'
5
  }
6
});
7

          
8
<div id="app">
9
  <date-picker date-format="dateFormat"></date-picker>
10
</div>


This would mean dateFormat would be a reactive data property. You could update its value at some point in the life of your app:

JavaScript




xxxxxxxxxx
1


 
1
// change the date format to something new
2
vm.dateFormat = 'yy-dd-mm';



Since the dateFormat prop is a dependency of the datepicker component's mounted hook, updating it would trigger the component to re-render. This would not be cool. jQuery has already set up your datepicker on the input and is now managing it with its own custom classes and event listeners. An update of the component would result in the input being replaced and thus jQuery's setup would be instantly reset.

We need to make it so that reactive data can't trigger an update in this component.

v-once

The v-once directive is used to cache a component in the case that it has a lot of static content. This in effect makes the component opt-out from updates.

This is actually perfect to use on our plugin component, as it will effectively make Vue ignore it. This gives us some confidence that jQuery is going to have unhampered control over this element during the lifecycle of the app.

HTML




xxxxxxxxxx
1


 
1
<div id="app">
2
  <date-picker date-format="yy-mm-dd" v-once></date-picker>
3
</div>


Passing Data From jQuery to Vue

It'd be pretty useless to have a datepicker if we couldn't retrieve the picked date and use it somewhere else in the app. Let's make it so that after a value is picked it's printed to the page.

We'll start by giving our root instance a date property:

JavaScript




xxxxxxxxxx
1
10


 
1
new Vue({
2
  el: '#app',
3
  data: {
4
    date: null
5
  }
6
});
7

          
8
<div id="app">
9
  <date-picker date-format="yy-mm-dd" v-once></date-picker>
10
  <p>{{ date }}</p>
11
</div>



The datepicker widget has an onSelect callback that is called when a date is picked. We can then use our component to emit this date via a custom event:

JavaScript




xxxxxxxxxx
1


 
1
mounted: function() {
2
  var self = this;
3
  $(this.$el).datepicker({
4
    dateFormat: this.dateFormat,
5
    onSelect: function(date) {
6
      self.$emit('update-date', date);
7
    }
8
  });
9
}



Our root instance can listen to the custom event and receive the new date:

JavaScript
xxxxxxxxxx
1
15
 
1
<div id="app">
2
  <date-picker @update-date="updateDate" date-format="yy-mm-dd" v-once></date-picker>
3
  <p>{{ date }}</p>
4
</div>
5
6
new Vue({
7
  el: '#app',
8
  data: {
9
    date: null
10
  },
11
  methods: {
12
    updateDate: function(date) {
13
      this.date = date;
14
    }
15
  }
16
});


Thanks to this Stack Overflow answer for inspiration.

JQuery UI Vue.js

Published at DZone with permission of Anthony Gore, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Mocking Dependencies and AI Is the Next Frontier in Vue.js Testing
  • Serving a Vue.js Application With a Go Backend
  • Build Full-Stack Web App With Firebase, Angular 15, React.js, Vue.js, and Blazor [Video]
  • React, Angular, and Vue.js: What’s the Technical Difference?

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!