【问题标题】:How does Vue overwrite jQuery event listenersVue如何覆盖jQuery事件监听器
【发布时间】:2019-04-13 10:22:59
【问题描述】:

我了解到 jQuery 和 Vue 不能很好地协同工作(参见例如https://vuejsdevelopers.com/2017/05/20/vue-js-safely-jquery-plugin/)。由于我有一个大型 jQuery 应用程序,我正在逐步将 Vue 整合到其中,我想了解幕后发生的事情,这样我就可以避免冲突。

这是一个简化的测试页面:

$('#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>

如您所见,第一个 (a) 事件侦听器被 Vue 清除,而其他三个 (b - d) 继续工作。

我的问题归结为,在技术层面上,Vue 对 (a) 所做的与 (b) 或 (d) 有何不同?

这里是 CodePen: https://codepen.io/MSCAU/pen/PxzQNq

【问题讨论】:

  • A 在脚本运行时被绑定。如果有任何东西破坏并重新创建了该元素(例如可能是 Vue 初始化),则绑定将丢失。 B 在文档被完全解析到 DOM 之后被绑定。这已经超出了所有这些脚本运行的程度。 Vue 运行并初始化,这可能会破坏现有的 A 元素并重新创建它,从而破坏原始绑定。一旦安装了 Vue,C 就会被绑定。一旦 Vue 完成了它要做的事情,D 就被绑定了。因此,如果 Vue 在到达该点之前重绘页面,则 D 将绑定到(新的)D 元素。
  • 但除此之外,这里的重点是,在使用 Vue 编码时不要使用 jQuery 进行绑定。使用 vue click 指令对元素进行绑定,不要使用 jQuery 来执行此操作。参考。 vuejs.org/v2/guide/events.html#Listening-to-Events
  • 我认为你应该避免将 jquery 与 VueJS、Angular 和 React 一起使用。
  • 您的按钮实际上是type="submit",因为您省略了类型。你确定这有帮助吗?
  • 除非 SO sn-p 功能不足,否则请下次将您的代码添加为 sn-p。

标签: jquery vue.js


【解决方案1】:

问题是.container(el)在beforeMount 事件触发之后和mounted 事件触发之前被Vue 替换。您可以在此处查看图表:

(reference)

举例说明:

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>

如您所见,原来的a 在beforeMount 之后、mounted 之前就丢失了。效果和容器的innerHTML被修改是一样的,例如

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

【讨论】:

  • 谢谢,@CertainPerformance。正如您所建议的那样,我向 CodePen 添加了一些 console.logs,我看到 (b) 事件侦听器是最后添加的。
  • 我以为 Vue 只影响包含指令的 HTML 元素,但显然不会。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多