2017-05-22

Vue + jQuery の弱点に初めて遭遇!

このところ Vue.js を使って開発効率が格段に上がってきているのを感じています。しかも以前の Vue.js 2.0 を使ってみた9つの感想 でも取り上げましたが、jQuery との衝突が全く無かったので機嫌よく Vue での開発を進めていたのですが、今回初めて衝突というか弱点に遭遇したのでまとめと対処法をお届けしたいと思います。



まずは遭遇した状況から。
jQuery(Bootstrap) を使ったページ内で JavaScript を使って input 内の値を変更しようとしました。(※詳しく言うと、後でも言及する datepicker を使ってテキスト内に日付を入力しようとしてました。また、冗長になるので、 this.input = 'xxxxxx'; を使うのは無しの方向です。)

私の頭の中では以下のように通常通り $('#id').val('xxxxx'); を使ってテキストの中身を変更すれば Vue の方でもデータが更新されるものだと思っていました。
しかし、以下のデモのようにテキスト内は変更できるものの、Vue の方では変更は全くないという状況でした。

Vue + jQuery の change イベント実験 - 1



、、、なぜだろう。
jQuery の val() でデータを変更しても change イベントは呼ばれないというのは知っていました(参考ページ)が、今回使っているのは vue の v-model なので問題はないはずなのに・・・?


そこで少し stackoverflow を探ってみると、vue には $forceUpdate() という強制的にデータを更新する方法があるよ、ということなので以下のページのように実際に試してみました。

Vue + jQuery の change イベント実験 - 2


でも、これもうまくいかない、、、、
クリックを続けているとたまに自動入力されるテキストがちらつくことがあるので、おそらく変更はされたが、$forceUpdate() によって瞬間的に元にもどされてしまっているという状況なのだろう(つまり Vue には伝わっていない)と思いました。


またしてもスタート地点に戻ってしまったので、もう一度いろいろとネット上の情報を探ってみると本家 GitHub の Issue で手がかり見つけました。

Triggering vuejs on programatical change of element.


どうやら、jQuery の changeイベントはネイティブの JavaScript のイベントとは別のものなので、もし Vue の変更をやりたいならネイティブイベントを作って dispatch しないといけないということでした。

そこで、早速以下のようにイベント送出をしてみました。

Vue + jQuery の change イベント実験 - 3


おっ、いけました!
この状態だと直接テキスト入力してもボタンをクリックしても Vue のデータが書き換わるのでリアルタイムに上のテキストも変更されるようになっています。

へぇ、Vue にはネイティブ JS のイベントが必要だったんですね。


では、本題の datepicker を使うにはどうすればいいのでしょうか。
今回は jQuery の changeイベントとのコラボでやってみました。

$('.datepicker').datepicker().on('change', function() {

    var event = document.createEvent('HTMLEvents');
    event.initEvent('input', true, true);
    $(this).get(0).dispatchEvent(event);

});

実際のテストは以下です。

Vue + jQuery の change イベント実験 - 4


やってみたら分かっていただけると思いますが、テキスト入力(数字しか入力できません)でもカレンダー選択のどちらでも Vue へデータが伝わっていると思います。

※ちなみに送出するイベントが「input」ではなく「change」の場合だと、これもうまくいきませんでした。

ということは、この方法を使えば「dispach-native-event」などのクラス名に changeイベントを作っておき、その中でネイティブ・イベントを送出することができるので、サイト全体での対処も比較的楽にできるかと思います。


んー、それにしてもこんな形で Vue + jQuery の問題点に遭遇するとは思いませんでした。
でもその他の部分では問題もなく、開発速度も上がり、保守もしやすいと思うので Vue の利用は続けていこうと思います。


【あとがき】

フロントエンド界の活動は近年ホントに活発でそれ自体はとてもいいことなのですが、正直なところをいうとたくさんありすぎてもう少し集約してほしい気はしています。
また、複雑さが年を追うごとにひどくなってきていて、「あれ、なんのためのフレームワークだったけ?開発効率、ほんとにこれで上がってる??」なんてことになってきているなぁ、と pythonプログラミングをしているとよく感じます。

この間どこかのブログで「3年後も react 使ってると思う? vue 使ってると思う? でも確実に jQuery は使ってるよね?」という趣旨の記事を読みました。

これには Vue が大好きな僕でも「確かにそれはあるかもー」と思いました。
そんなこんなもあるので、変化の速い(早すぎる)これからのプログラミングは学習コストの低さも重要なファクターの一つになってくるんじゃないかな、と今日出してきた扇風機にあたりながら考えてました。
(もちろん何を専門にするかで変わってくるでしょうけどね。)


それはともかく、今年の夏は涼しかったらいいなー(笑)




0 件のコメント:

コメントを投稿