Reputation: 2356
I have a some custom JQuery code that listen to events and add some classes to form elements (focus, blur, odd/even, etc). Nothing big but I would like not to re-writte all this logic in VueJS since all the website use only JQuery and 1 page uses VueJS for a complex form.
I wrote a Directive to launch the JQuery code on new VueJS elements and it's working. But some VueJS code (vee-validate
directive plugin in my case but it can be any VueJS code) changes the classes using v-bind:class
. So it erase the classes sets by JQuery, it doesn't add its classes it replace them... Is there any way to play nicely with classes from VueJS and JQuery/Javascript ? Make JQuery aware of existing classes or something.
Thanks
Upvotes: 1
Views: 1388
Reputation: 5986
You can accomplish this with a MutationObserver
https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
The following example will set up a vuejs app that when clicked on changes the class from on to off and back modifying the class list via vue. It will then set up a mutation observer to look for changes to the class attribute and run some more jquery to check if a makeBold
class is in the class list and if not add it.
this demonstrates that vue is controlling the elements class list and the observer is reacting to changes by executing some jquery
additionally i have added a checkbox to disable the oberserver reaction to show that vue is removing the makeBold class
const app = new Vue({
el: '#app',
data() {
return {
on: true
}
}
})
const node = document.getElementById('app')
// add bold class with jQuery
$('#app').addClass('makeBold')
const observer = new MutationObserver(mutations => {
if ($('#cbx').prop('checked')) return
const changes = mutations
.filter(({ attributeName }) => attributeName === 'class');
if (changes.length && !$('#app').hasClass('makeBold')) {
$('#app').addClass('makeBold')
}
})
observer.observe(node, { attributes: true })
.on {
background-color: orange;
}
.off {
background-color: white;
}
.makeBold {
font-weight: 600;
}
.appBody {
height: 100px;
border: 1px solid #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.11/vue.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="app" class="appBody" :class="{ 'on': on, 'off': !on }" @click="on=!on">
Click Me
</div>
<input type="checkbox" id="cbx"> Disable Observer reaction
Upvotes: 2