web-dev-qa-db-ja.com

VueJSとjQueryをうまく動作させる

この質問は intl-tel-inputとvuejs2を一緒に使用する に関連/類似していますが、未回答です。

そして VueJSはデータ属性値としてpropを使用します これには解決策がありますが、「環境」について少し説明しています。

要するに、新しいbootstrap=タブ(タイトルとURL)を動的に設定し、jQueryを使用して一部の機能を(再)バインドしようとしています。

次の行を追加します https://github.com/thecodeassassin/bootstrap-remote-data/blob/master/js/bootstrap-remote-tabs.js#L258 in my Vueメソッドは機能を適用しますが、変更を2回トリガーした場合のみです。

最初の(未回答の)質問と同じ問題。

誰かがvueJSjQueryの間で物事がどのように機能するかを少し説明できますか?そして、できればjQueryパッケージを書き換える必要なく、物事を解決する方法。

もし私が console.log私の変数は、一歩遅れているように見えます。

LE:

関連する言及された問題のためにペンを準備しました: https://codepen.io/AngelinCalu/pen/LWvwNq

14
Angelin Calu

Vueを他のDOM操作ツールキットとうまく連携させる方法は、それらを完全に分離することです。jQueryを使用してDOMウィジェットを操作する場合は、Vueも使用しませんその上(およびその逆)。

ラッパーコンポーネント はブリッジとして機能し、Vueはコンポーネントと対話でき、コンポーネントはjQuery(またはその他)を使用して内部DOM要素を操作できます。

ライフサイクルフック 以外のjQueryセレクターは、悪臭を放ちます。 validatePhoneNumberはセレクターとDOM操作呼び出しを使用しますが、Vueを使用してkeydownイベントを処理しています。このウィジェットのすべてをjQueryで処理する必要があります。 Vueを使用してクラスまたは電話番号を設定したり、イベントを処理したりしないでください。これらはすべてDOM操作です。先ほど述べたように、コンポーネントでラップすると、コンポーネントに小道具を渡すことができ、それらの小道具からjQueryを使用してclassとphone_numberを設定できます。

15
Roy J

その背後にある理由は、 keydownイベントが発生したとき であり、プラグインの内部動作が開始され、電話の値がすぐに公開されないためだと思います。これにより、プラグイン自体によって内部的に更新される前に、電話番号の値を早々に取得するという競合状態が発生します。

この問題は、keyupinputなどの他のイベントをリッスンすることで簡単に解決できます。

const app = new Vue({
  el: '#app',

  data: {
    phone_number: "",
    validPhone: false
  },


  methods: {
    validatePhoneNumber: function() {
      var phone_element = $('#phone');
      var validPhoneNo = phone_element.intlTelInput("isValidNumber");
      var phoneNo = phone_element.intlTelInput("getNumber");
      console.log(phoneNo + ' -> ' + validPhoneNo); // I am interested in both values
    }
  },


  mounted: function() {
    $('#phone').intlTelInput({
      utilsScript: "js/utils.js",
      initialCountry: "auto",
      geoIpLookup: function(callback) {
        $.get('https://ipinfo.io', function() {}, "jsonp").always(function(resp) {
          var countryCode = (resp && resp.country) ? resp.country : "";
          callback(countryCode);
        });
      },
      preferredCountries: []
    });
  }
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/11.0.10/css/intlTelInput.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/Twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.4/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/11.0.10/js/utils.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/11.0.10/js/intlTelInput.min.js"></script>

<div id="app">
  <div class="row">
    <div class="col-sm-offset-2 col-sm-6">
      <input class="form-control" @input="validatePhoneNumber" :class="{validInput: validPhone }" name="phone" value="" ref="phone_element" :phone_number="phone_number" type="text" id="phone" />
    </div>
  </div>
</div>

競合状態が続く可能性があるため、これはまだ理想的な解決策ではないことを認めざるを得ません。競合状態が存在しないことを確認する唯一の方法は、VueJSの入力要素でリッスンできる電話番号の解析と検証が完了したら、プラグインがカスタムコールバックをトリガーするのを待つことです。今のところ、プラグインには国を変更するためのカスタムコールバックしかありません。

3
Terry