【Vue.js】【jQuery】Vue.js のコンポーネント内に jQuery の機能を置く

  • 2021年2月1日
  • 2021年2月2日
  • Vue, jQuery

 Vue.js は JavaScript のフレームワークでコンポーネント単位での開発を容易にし、巨大な機能を持つページも比較的容易に開発できます。
 新規機能の開発を楽にしたいので Vue.js を使いたい、という時がままありますが既存のプロジェクトには jQuery が組み込まれている時が少なくなく、既存の jQuery 込みのデザインを崩すことは好まれません。そこで Vue.js と jQuery を組み合わせコードの需要があります。
 Vue.js と既存の jQuery の組み合わせで面倒なのは Vue.js が Vue.js の都合で自由に DOM を追加、削除することによって jQuery によるイベント指定がしょっちゅう外れ、初期化もうまくいかないことです。input 要素の拡張やアニメーションのライブラリは特にこれが顕著です。これを Vue.js のコンポーネント内に jQuery のライフサイクルを組み込むことで対策します。
 例えば、次の様にできます。

クリックでソースコードを展開
<template>
  <input type="text" class="form-control calendar" />
</template>

<script>
/**
 * ↓を元にした jquery 1.8.3 + bootstrap-datepicker 1.5 を扱うためのコンポーネントです
 * @see https://github.com/ankurk91/vue-bootstrap-datetimepicker
 */
export default {
  name: "DatePicker",
  props: {
    value: {
      default: null,
      validator(value) {
        return (
          value === null ||
          value instanceof Date ||
          typeof value === "string" ||
          value instanceof String
        );
      },
    },
    config: {
      type: Object,
      default: () => ({// datepicker のデフォルト設定
        format: "yyyy/mm/dd",
        language: "ja",
        autoclose: true,
        clearBtn: true,
        orientation: "top auto",
      }),
    },
  },
  data() {
    return {
      dp: null, // DatePicker
      jqEl: null, // jQuery DOM Element
    };
  },
  watch: {
    /**
     * 外からの値の変化を監視して datepicker まで渡す
     * @param {mixed} newValue
     */
    value(newValue) {
      this.dp && this.dp.setValue(newValue || null);
    },

    /**
     * 外からの設定の変化を監視して datepicker まで渡す
     * @param {Object} newConfig
     */
    config: {
      deep: true,
      handler(newConfig) {
        this.dp && this.dp.options(newConfig);
      },
    },
  },
  mounted() {
    // 定義済みならば処理なし
    if (this.dp) {
      return;
    }
    this.jqEl = $(this.$el); // Vue内のルート要素をjQuery化して取得
    this.jqEl.datepicker(this.config); // datepicker を初期化
    this.dp = this.jqEl.data().datepicker; // datepicker を bind
    this.dp.setValue(this.value); // datepicker に初期値を代入
    // 親コンポーネントの :input とこのコンポーネントの DatePicker の変化を紐づけ。主に v-model 用
    this.jqEl.on("change", (event) =>
      this.$emit("input", event.currentTarget.value)
    );
    // 上に伝播させるイベントをまとめて登録
    ["hide", "show", "change", "error", "update"].forEach((name) => {
      this.$el.addEventListener(name, (...args) => {
        this.$emit(name, ...args);
      });
    });
  },
  /**
   * DatePicker, jQuery を掃除。
   * Vueの管理外なので都度DatePickerを破壊する必要がある
   */
  beforeDestroy() {
    if (this.dp) {
      this.dp.destroy();
      this.dp = null;
      this.jqEl = null;
    }
  },
};
</script>

 この様にすると次の様に簡単に jQuery 付きのコンポーネントを呼び出せます。

    <DatePicker v-model="hoge_date" />

 プログラムの内容を端的に言うと mounted 時に jQuery ライブラリによる初期化を行い、 beforeDestroy 時にリセットにします。そして何かイベントが起きた時に都度 jQuery と Vue.js の仲介をします。jQuery と Vue.js の間でアダプターパターンをする感じです。jQuery のことはコンポーネント内に任せて、外には Vue.js
用の値とイベントのやり取りだけ出すとすっきりしやすいです。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG