How does Vue overwrite jQuery event listeners

做~自己de王妃 提交于 2021-01-29 05:09:39

问题


I have read that jQuery and Vue tend not to work very well together (see eg. https://vuejsdevelopers.com/2017/05/20/vue-js-safely-jquery-plugin/). As I have a large jQuery app that I am progressively incorporating Vue into, I'd like to understand what's going on under the hood so I can avoid conflicts.

Here's a simplified test page:

$('#a').click(function() {
  alert('a');
});

$(function() {
  $('#b').click(function() {
    alert('b');
  });
});

var app = new Vue({
  el: '.container',
  mounted: function() {
    $('#c').click(function() {
      alert('c');
    });
  }
});

$('#d').click(function() {
  alert('d');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <button id="a">a - jQuery immediate</button>
  <button id="b">b - jQuery DOM ready</button>
  <button id="c">c - jQuery inside Vue mounted</button>
  <button id="d">d - jQuery after Vue</button>
</div>

As you can see, the first (a) event listener gets wiped out by Vue whereas the other three (b - d) continue to work.

My question boils down to, at a technical level, what is Vue doing to (a) which is different from (b) or (d)?

CodePen here: https://codepen.io/MSCAU/pen/PxzQNq


回答1:


The problem is that the .container (the el) gets replaced by Vue right after the beforeMount event fires, and right before the mounted event fires. You can see a diagram here:

(reference)

To illustrate:

const a = document.querySelector('#a')
const app = new Vue({
  el: '.container',
  beforeMount: () => {
    console.log(a === document.querySelector('#a'));
  },
  mounted: function() {
    console.log(a === document.querySelector('#a'));
  }
});
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
<div class="container">
  <h1>Vue vs jQuery</h1>
  <button id="a">button</button>
</div>

As you can see, the original a gets lost right after beforeMount, right before mounted. The effect is the same as if the innerHTML of the container was altered, eg

document.querySelector('.container').innerHTML += ' ';


来源:https://stackoverflow.com/questions/53232661/how-does-vue-overwrite-jquery-event-listeners

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!