1

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

Mushr00m
  • 2,258
  • 1
  • 21
  • 30
  • It sounds like you will have to assign your JQuery classes later in the lifecycle (perhaps in `mounted`) on the component rather than in the directive. – webnoob Dec 11 '17 at 00:47
  • Expanded on what was said above, lifecycle hooks in general should be a consideration for you to look into. The `mounted` and `updated` hooks are likely the ones you'll be most interested in. – B. Fleming Dec 11 '17 at 00:55
  • It's not what you're looking for, but it is how you make jQuery and Vue play nice. https://stackoverflow.com/a/43255516/392102 – Roy J Dec 11 '17 at 02:49
  • Thanks for your replies but I'm using a `Directive` not a `Component`. Because I need to attach multiples directives to an element and with a component it's only one. Your example about `mounted` and `updated` are for `components`. – Mushr00m Dec 11 '17 at 08:56

1 Answers1

2

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
vbranden
  • 5,814
  • 2
  • 22
  • 15