问题
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