Vue.jsで開発していると、「このコンポーネントのpropsやdata、今どうなっている?」と確認したい場面は日常的にあります。Vue DevToolsを使うのが一般的ですが、DevToolsが使えない環境や、コンソールから素早く値を確認したいケースもあるでしょう。
この記事では、Vueが内部的にDOM要素に付与する__vue__プロパティを中心に、Vue 2とVue 3それぞれのデバッグ手段を紹介します。
__vue__とは何か
VueがコンポーネントをDOMにマウントする際、対象のDOM要素にはVueインスタンスへの参照が内部プロパティとして付与されます。このプロパティが__vue__であり、ブラウザのコンソールからコンポーネントの内部状態に直接アクセスできる手段となります。
あくまで開発時のデバッグ用途で公開されている非公式な内部プロパティであるため、本番コードでの使用は想定されていません。
Vue 2での__vue__の使い方
もっとも手軽な方法は、ブラウザの開発者ツールのElementsパネルで対象のDOM要素を選択し、コンソールで$0.__vue__と入力することです。
$0とは?
$0はElementsパネルで現在選択中の要素を指します
document.querySelector で取得するのと同じDOM要素オブジェクトです
そのため$0.__vue__これだけでコンポーネントインスタンス全体が展開され、$data、$props、computed、methodsなどをすべて確認できます。
// Elementsパネルで選択中の要素から__vue__にアクセス
$0.__vue__
特定のプロパティだけ確認したい場合は、ドット記法で辿ります。$0.__vue__.$dataでdata全体、$0.__vue__.$data.isLoadingで個別の値、$0.__vue__.$propsでprops、$0.__vue__.computedPropertyNameでcomputedプロパティにそれぞれアクセスできます。
$0.__vue__.$data
$0.__vue__.$data.isLoading
$0.__vue__.$props
$0.__vue__.computedPropertyName
Elementsパネルを使わずにdocument.querySelectorでセレクタ指定する方法もあります。
document.querySelector('#app').__vue__
document.querySelector('.my-component').__vue__.$data
さらに、値の確認だけでなく、コンソールから直接値を書き換えてUIの変化を確認することも可能です。
$0.__vue__.$data.isLoading = true
Vue 3での変更点
Vue 3では__vue__プロパティが廃止され、内部構造が大きく変わりました。アプリのルート要素には__vue_app__が付与されます。
document.querySelector('#app').__vue_app__
個々のコンポーネントには__vueParentComponentが付与されていますが、アクセスの仕方はVue 2より複雑です。propsは$0.__vueParentComponent.props、Composition APIのsetup内に定義したリアクティブデータは$0.__vueParentComponent.setupStateに格納されています。Vue 2のように$dataで統一的にアクセスできない点に注意が必要です。
$0.__vueParentComponent
$0.__vueParentComponent.props
$0.__vueParentComponent.setupState
また、開発モード(devtools: true)でないとこれらの内部プロパティが公開されない場合があります。
Vue 2とVue 3の比較
| 項目 | Vue 2 | Vue 3 |
|---|---|---|
| インスタンスアクセス | el.__vue__ | el.__vueParentComponent |
| アプリルート | el.__vue__.$root | el.__vue_app__ |
| dataの確認 | el.__vue__.$data | el.__vueParentComponent.setupState |
| propsの確認 | el.__vue__.$props | el.__vueParentComponent.props |
| 直感的かどうか | シンプル | やや複雑 |
より実践的なデバッグテクニック
テンプレート内でのconsole.log
テンプレート内に直接{{ console.log(someData) }}と書くことはできませんが、methodsにlogメソッドを定義して{{ log(someData) }}とすれば、描画のたびにコンソールへ出力できます。
// Vue 2
methods: {
log(value) {
console.log(value)
return ''
}
}
// Vue 3 Composition API
const log = (value) => {
console.log(value)
return ''
}
watchで変化を追跡する
特定のデータがいつ・どう変わったかを追いたい場合、一時的にwatchを仕込むのが有効です。deep: trueを指定すれば、ネストしたオブジェクトの変更も検知できます。
// Vue 2
watch: {
someData: {
handler(newVal, oldVal) {
console.log('変更検知:', oldVal, '->', newVal)
},
deep: true
}
}
// Vue 3
watch(someData, (newVal, oldVal) => {
console.log('変更検知:', oldVal, '->', newVal)
}, { deep: true })
debugger文の活用
コード中にdebuggerと書くと、開発者ツールを開いた状態でその行に到達した時点でブレークポイントが発動します。console.logではその時点の値しか見えませんが、debuggerならスコープ全体を調べられるため、より強力なデバッグ手段になります。
methods: {
handleClick() {
debugger // ここで止まる
this.doSomething()
}
}
Vue DevToolsとの使い分け
日常的なデバッグにはVue DevToolsが最適です。コンポーネントツリーの可視化、リアクティブデータのリアルタイム確認・編集、Vuex/Piniaのストア監視、イベント追跡などが視覚的に行えます。
一方、__vue__や__vueParentComponentが活きるのは、DevToolsが使えない環境(CI上のブラウザ、拡張がインストールできない制約がある場合など)や、スクリプトから自動的に値を取得したい場面です。
console.logやdebuggerは、コードの特定箇所でピンポイントに値を確認したい場合や、処理フローを追いたい場合に使います。状況に応じてこれらを組み合わせることで、あらゆるデバッグシーンに対応できます。
まとめ
__vue__はVueが内部的にDOMに付与するプロパティで、コンソールからコンポーネントインスタンスに直接アクセスできる仕組みです。Vue 2ではel.__vue__でシンプルにアクセスできましたが、Vue 3ではel.__vueParentComponentに変わり、データの格納場所もsetupStateに移行しています。
日常のデバッグにはVue DevToolsが最も効率的ですが、__vue__の仕組みを知っておくとDevToolsが使えない場面で助けになります。console.log、watch、debuggerと組み合わせれば、開発中に遭遇するほとんどのデバッグシーンをカバーできるでしょう。