Vueコンポーネント内でJqueryプラグインを使う方法

Laravel

Laravel + Vue.jsで開発をしています

一応正式な形に則って、動的な更新をVueコンポーネントに委託しています

ところがちょっと困ったのが、Vueコンポーネント内でJqueryプラグインを動かす方法です

Tagsinput.js

今回使いたかったのは、タグインプットプラグインであるbootstrap4-tagsinput

このプラグインについての導入の仕方はこちらをご覧ください

このJqueryプラグインをVueコンポーネント内に適用しようとして不具合が発生しました

構成

今回のファイル構成はこんな感じです

Bladeファイル

@section('content')
  <div>
    <div id="app">
      <my-component></my-component>
    </div>
  </div>
@endsection

Vueコンポーネント

<template>
  <div v-for="(user,index) in users" :key="index">
    {{ user.name }}
  </div>
</template>
 
<script>
  export default {
    data() {
        return {
            users: []
        };
    },
    mounted() {
        axios
            .get("/api/getusers/")
            .then(response => (this.users = response.data));
    },
</script>

APIの内容は省略しますが、簡単に説明すると

Vueコンポーネント内で動的に取得したユーザデータを、template内のv-forで回して表示します

ユーザ数分の名前が動的に生成されるわけですね

不具合

長い前提が終わりやっと不具合の説明となるわけですが、

このユーザの名前欄の下にTagsinputを表示したかったわけですよ

<template>
  <div v-for="(user,index) in users" :key="index">
    {{ user.name }}
    <input id="tags" name="tags" class="tags" type="text" data-role="tagsinput" value="Jquery,PHP">
  </div>
</template>
 
<script>
  export default {
    data() {
        return {
            users: []
        };
    },
    mounted() {
        axios
            .get("/api/getusers/")
            .then(response => (this.users = response.data));
    },
</script>

こんな感じで

なのでapp.jsにTagsinputのファイルを追加して、いざ準備万端と思いきや、タグとして表示されない

解決法

「Vueコンポーネントのupdated内でTagsinputを初期化する」

です

<template>
  <div v-for="(user,index) in users" :key="index">
    {{ user.name }}
    <input id="tags" name="tags" class="tags" type="text" data-role="tagsinput" value="Jquery,PHP">
  </div>
</template>
 
<script>
  export default {
    data() {
        return {
            users: []
        };
    },
    mounted() {
        axios
            .get("/api/getusers/")
            .then(response => (this.users = response.data));
    },
    updated(){
        $('.tags').tagsinput()
    }
</script>

そもそもTagsinputはJavaScript側から明示的に初期化する必要はありません

Bladeファイルの読み込み時に一旦Tagsinputの初期化が走るんですが、タイミング的に動的に生成されるVueコンポーネント内のtagはかなり後になるので、ここに適用されないのが原因でした

updatedはデータの更新後に実行されるVueのライフサイクルフックです

動的なデータ取得(axios)がなければmounted内でも大丈夫だと思います

つまり、動的に生成されたデータが構成された後で初期化を明示的に実行するわけですね

ふう、これでちゃんとVueコンポーネント内でもJqueryプラグインが実行できるようになりました