同时使用 Vue.js 和 jQuery 自动完成

Use both Vue.js and jQuery autocomplete

我想同时使用 Vue.js 和 jQuery 来动态显示自动完成字段。

new Vue({
  el: "#el",
  data: {
    toggle: false
  }
});

var tags = [
  "ActionScript","AppleScript","Asp","BASIC","C","C++","Clojure","COBOL","ColdFusion",
  "Erlang","Fortran","Groovy","Haskell","Java","JavaScript","Lisp","Perl","PHP","Python",
  "Ruby","Scala","Scheme"
];

$("#autocompleteSearch").autocomplete({
  source: tags
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="https://unpkg.com/vue"></script>

<div id="el">
  <input v-if="toggle" id="autocompleteSearch" type="search">
  <button @click="toggle=!toggle">Toggle</button>
</div>

如您所见,由于输入中的 v-if,它无法工作。如果我删除 v-if 它可以工作,但它不会动态显示。我该怎么办?

这里有几点需要注意。

$(selector) 在那个时间点查找现有的 DOM 元素

对于 jQuery 查找元素,执行查找时它必须存在于 DOM 中。关于 DOM 片段有一些警告,但这与这个特定问题无关。所以请记住,要让 jQuery 找到某些东西,它必须存在于 DOM.

许多jQuery UI 方法初始化和转换元素

当您执行 jQuery UI 方法(如自动完成)时,jQuery 会更改并在页面上创建与您定位的元素相关的标记。这些方法还可以将与元素相关的内部变量作为其初始化的一部分。

v-if 创建和销毁元素

v-if 的目的是说,一个元素应该只存在 if 某些条件为真。所以如果条件为假,它就不会存在于DOM中。此外,如果此条件可能会发生变化,则可能会多次创建和销毁该元素。


所以考虑到v-if的工作原理,我们可以反思前面两点。

  • 如果v-if使得jQuery选择器运行时元素不存在,它将找不到要初始化的元素
  • 如果 v-if 破坏了一个元素,jQuery UI 小部件可能无法正常运行,因为它与它初始化的元素相关,而不是未来的元素创建以替换先前创建的元素。

考虑到这一点,在使用 Vue 和 jQuery 时,您必须牢记两者的需求,以及它们如何相互冲突,例如在本例中。当 v-if 控制的元素也用作另一个库中状态的一部分时,使用 v-if 不一定是最好的指令,例如 jQuery.

为了解决这个问题,您可以选择使用其他指令,例如 v-showv-hide

v-showv-hide是一枚硬币的两面。他们决定一个元素是否应该对用户可见。这两个指令与 v-if 的明显区别在于 v-showv-hide 不会从 DOM 中删除元素。它们只是改变元素的显示状态。

因此,对于依赖于现有元素并将该元素用作某些状态管理的一部分的另一个库而言,这太棒了!您可以控制用户何时看到元素,也可以避免与辅助库发生冲突,例如 jQuery UI.


话虽如此,但这并不意味着您不应该使用 v-ifv-if 对于在某些时间点不应存在的元素仍然有用。所有这一切意味着您应该意识到您正在制造的情况,并考虑您的应用程序中可能依赖于这些元素的任何其他逻辑,以最大限度地减少产生错误的机会。


TL;DR;

这是您问题的解决方案:

new Vue({
  el: "#el",
  data: {
    toggle: false
  }
});

var tags = [
  "ActionScript","AppleScript","Asp","BASIC","C","C++","Clojure","COBOL","ColdFusion",
  "Erlang","Fortran","Groovy","Haskell","Java","JavaScript","Lisp","Perl","PHP","Python",
  "Ruby","Scala","Scheme"
];

$("#autocompleteSearch").autocomplete({
  source: tags
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="https://unpkg.com/vue"></script>

<div id="el">
  <!-- Just replace v-if by v-show -->
  <input v-show="toggle" id="autocompleteSearch" type="search">
  <button @click="toggle=!toggle">Toggle</button>
</div>