【Vue 2.x】Vueコンストラクタ関数をWebコンソール上で見つける方法


Vue コンストラクタ関数とは?

Vue.js 2.x 系を webpack などのバンドラと共に使用している方にとっては、この Vue のことです:

import Vue from 'vue';
       ^^^

<script> タグを貼り付けるだけのいわゆる「CDN版」の Vue.js を利用している場合は window.Vue で簡単に Vue コンストラクタ関数を参照できますが、バンドラを用いてビルドされている場合においても Vue コンストラクタ関数を参照できる方法を紹介します。

動作環境

  • Vue.js 2.6.11 などの Vue.js 2.x 系
  • Chrome 80
    • Vue.js devtools 5.3.3

Vue コンストラクタ関数の参照を得る方法

以下のスクリプトをWebコンソール上で実行することで、Vue コンストラクタ関数を参照することができます:

const Vue = (() => {
  const el = [].find.call(document.all, el => el.__vue__);
  if (!el) {
    return;
  }
  let Vue = Object.getPrototypeOf(el.__vue__).constructor;
  while (Vue.super) {
    Vue = Vue.super;
  }
  return Vue;
})();

Vue 公式のブラウザ拡張である Vue.js Devtools の実装を参考にしました。
Internet Explorer 11 に対応した実装が必要であれば、こちらの Gist を参照してください。

応用

プロダクションビルドされていても Vue.js Devtools を有効にする

2019年6月に Apple の SwiftUI のチュートリアルサイトが Vue.js で構築されていることが話題になりましたが、プロダクションビルドされたものにも関わらず Vue.js Devtools が有効となっていることにも驚いた方が多かったようです。

この Twitter のやりとりをご覧になった @mottox2 さんがブレークポイントを挿入して Vue コンストラクタ関数を見つける方法1を紹介されていましたが、やり方を変えたものがこちらのスクリプトとなります:

(() => {
  if (!__VUE_DEVTOOLS_GLOBAL_HOOK__) {
    return;
  }
  const el = [].find.call(document.all, el => el.__vue__);
  if (!el) {
    return;
  }
  let Vue = Object.getPrototypeOf(el.__vue__).constructor;
  while (Vue.super) {
    Vue = Vue.super;
  }
  Vue.config.devtools = true;
  __VUE_DEVTOOLS_GLOBAL_HOOK__.Vue = Vue;
})();

上記スクリプトをコンソールで実行後、デベロッパーツールを開き直すと "Vue" タブが出現します。

バージョン情報の取得・ランタイム限定ビルドであるか判定する

ランタイムビルド・完全ビルドについて詳しくはVue.js 公式ガイドの「さまざまなビルドについて」を参照してください。

(() => {
  const el = [].find.call(document.all, el => el.__vue__);
  if (!el) {
    return;
  }
  let Vue = Object.getPrototypeOf(el.__vue__).constructor;
  while (Vue.super) {
    Vue = Vue.super;
  }
  console.log('Vue.version:', Vue.version);
  console.log('Vue.compile:', Vue.compile);
})();

ランタイム限定ビルドの場合は、 Vue.compileundefined となっています:

完全ビルドの場合は、 Vue.compile が定義されています:

状態を変更したり特定のページに遷移したりする

Vue コンストラクタ関数を見つける方法と近い方法で ViewModel を見つけることもできます2
ViewModel を見つければ、特定の状態に変更したり、特定の画面に遷移することなどが可能です:

(async () => {
  const $root = [].find.call(document.all, el => el.__vue__).__vue__.$root;
  await $root.$store.dispatch('HOGE_ACTION'); // Vuex
  $root.$router.push(`/fuga/path`); // Vue Router
})();

投稿完了画面など、実際に操作して遷移させるのが面倒な画面の CSS を書いたりするときに便利かもしれません。