ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
Vue.js でよく遭遇するエラー一覧
Vue 3 を中心に、開発で頻出するエラーと対処をまとめます。多くは Vue 2 にも当てはまります。
1. Failed to mount component
[Vue warn]: Failed to mount component: template or render function not defined.
[Vue warn]: Property "xxx" was accessed during render but is not defined on instance.
原因と対処:
- SFC で
<template>ブロック忘れ → 追加 defineComponent戻り値のtemplateプロパティが未定義 →renderまたはtemplate追加- 動的 import 失敗 → ファイルパス / 拡張子確認
- Volar / TypeScript 設定で SFC 認識不能 →
tsconfig.jsonのvueCompilerOptions確認
<!-- ❌ template ブロック無し -->
<script setup>
const msg = 'hi'
</script>
<!-- ✅ -->
<script setup>
const msg = 'hi'
</script>
<template>
<div>{{ msg }}</div>
</template>
2. Cannot read properties of undefined (リアクティビティ)
TypeError: Cannot read properties of undefined (reading 'name')
非同期データの初期値が未定義のままレンダリングされた典型例:
<script setup>
import { ref, onMounted } from 'vue'
const user = ref(null)
onMounted(async () => {
user.value = await fetch('/api/me').then(r => r.json())
})
</script>
<template>
<!-- ❌ user.name で user が null -->
<div>{{ user.name }}</div>
<!-- ✅ パターン1: v-if でガード -->
<div v-if="user">{{ user.name }}</div>
<!-- ✅ パターン2: オプショナルチェイニング -->
<div>{{ user?.name }}</div>
<!-- ✅ パターン3: 初期値を与える -->
<!-- script 側: const user = ref({ name: '' }) -->
</template>
3. ref / reactive の誤用
import { ref, reactive } from 'vue'
// ❌ ref を渡されたつもりで生の値を扱う
const count = ref(0)
console.log(count + 1) // → "[object Object]1"
// ✅
console.log(count.value + 1)
// ❌ reactive オブジェクトを分割代入 → リアクティビティ消失
const state = reactive({ name: 'a' })
const { name } = state // 普通の文字列
name = 'b' // ❌ state.name は変わらず
// ✅ toRefs で個別 ref 化
import { toRefs } from 'vue'
const { name } = toRefs(state)
name.value = 'b' // ✅ state.name も更新
// ❌ reactive を再代入
let s = reactive({ a: 1 })
s = { a: 2 } // ❌ リアクティビティ切断
// ✅ プロパティを更新
s.a = 2
// または ref + .value で全置換
const sref = ref({ a: 1 })
sref.value = { a: 2 } // ✅
4. v-model が動かない (カスタムコンポーネント)
Vue 3 の v-model は modelValue + update:modelValue イベント。
<!-- 親 -->
<MyInput v-model="text" />
<!-- ❌ Vue 2 流儀 (動かない) -->
<script>
export default {
props: ['value'],
emits: ['input'],
}
</script>
<!-- ✅ Vue 3 -->
<script setup>
defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
</script>
<template>
<input :value="modelValue"
@input="emit('update:modelValue', $event.target.value)" />
</template>
<!-- ✅ defineModel (Vue 3.4+, より簡潔) -->
<script setup>
const text = defineModel()
</script>
<template>
<input v-model="text" />
</template>
5. Vue 2 → 3 移行で消えた API
| Vue 2 | Vue 3 での扱い |
|---|---|
Vue.filter('xxx', fn) | 廃止。computed や methods で代替 |
Vue.prototype.$xxx | app.config.globalProperties.$xxx |
$listeners | $attrs に統合 |
v-on.native | 不要 (デフォルトでネイティブ) |
v-model.sync | v-model:xxx + 複数 v-model |
new Vue({...}) | createApp({...}).mount(...) |
| Functional Component | 関数で書くだけ (props 引数) |
Vue.set / Vue.delete | 不要 (Proxy ベースリアクティビティ) |
EventBus (new Vue()) | mitt 等の外部ライブラリ推奨 |
6. Vue Router の動的ルート
// Vue Router 4
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/users/:id', component: UserDetail },
{ path: '/users/:id(\\d+)', component: UserDetail }, // 数値のみ
{ path: '/files/:path(.*)*', component: FileView }, // catch-all
],
})
// 動的ルートで同じコンポーネントが再利用される
// → 同じコンポーネントだとライフサイクル発火しない
// 対処: route.params を watch
import { watch } from 'vue'
import { useRoute } from 'vue-router'
const route = useRoute()
watch(() => route.params.id, async (newId) => {
await loadUser(newId)
}, { immediate: true })
// or :key で強制再生成
// <router-view :key="$route.fullPath" />
7. Pinia (推奨ストア)
// store/counter.js
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const double = computed(() => count.value * 2)
function increment() {
count.value++
}
return { count, double, increment }
})
// コンポーネントから
<script setup>
import { useCounterStore } from '@/store/counter'
import { storeToRefs } from 'pinia'
const store = useCounterStore()
const { count, double } = storeToRefs(store) // リアクティブ維持
const { increment } = store // 関数は分割代入 OK
</script>
8. Production 警告を抑制
// main.js
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
// 開発環境のみ警告ハンドラ
app.config.warnHandler = (msg, instance, trace) => {
if (msg.includes('Component name')) return // 特定警告を抑制
console.warn(msg, trace)
}
// 本番では Vue 自体が警告を出さない (vue.runtime.prod.js)
app.mount('#app')
9. Vue DevTools 利用
- Chrome 拡張 / Firefox アドオン: 「Vue.js devtools」
- スタンドアロン版:
npm i -g @vue/devtools→vue-devtools起動 - コンポーネントツリー / Pinia ストア / イベント / Performance を可視化
- 本番ビルドでは無効化される。デバッグしたい場合は
__VUE_PROD_DEVTOOLS__ = true
10. Nuxt の Hydration mismatch
[Vue warn]: Hydration node mismatch:
- Client vnode: <div>...
- Server rendered DOM: <span>...
Hydration completed but contains mismatches.
原因: SSR と CSR で生成される DOM が異なる (時刻、Math.random、window 参照など)。
<!-- ❌ サーバとクライアントで違う値 -->
<div>{{ new Date().toLocaleString() }}</div>
<!-- ❌ window はサーバに無い -->
<div>{{ window.innerWidth }}</div>
<!-- ✅ ClientOnly で囲む (Nuxt) -->
<ClientOnly>
<div>{{ new Date().toLocaleString() }}</div>
</ClientOnly>
<!-- ✅ onMounted で window を扱う -->
<script setup>
import { ref, onMounted } from 'vue'
const width = ref(0)
onMounted(() => { width.value = window.innerWidth })
</script>
<!-- ✅ useState / useFetch でサーバ側で確定させてから渡す -->
<script setup>
const { data } = await useFetch('/api/now') // SSR で確定
</script>
FAQ
Q: watch が発火しない
A: ref なら watch(myRef, ...)、reactive 内プロパティは watch(() => state.x, ...) のように関数で。
Q: コンポーネントが再描画されない
A: リアクティビティ切断 (分割代入、再代入)。toRefs や ref 化で解決。
Q: provide / inject がアプリ全体で動かない
A: app.provide(key, value) をルートで設定。コンポーネント内 provide はサブツリーのみ有効。
Q: TypeScript で props の型が効かない
A: defineProps<{ id: number }>() でジェネリック指定。または defineProps({ id: { type: Number, required: true } })。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
同階層のページ
- インストール(ファイルのダウンロード)
- npmを使用したプロジェクトの作成
- for 繰り返し処理
- ifの条件分岐とtemplateを用いたグループ化
- クリック時のイベント処理(on:click)
- modelとdata フォーム入力値とDOMへの即時反映
- computed(算出プロパティ)と使い方とdataとの違い
- ライフサイクルフック(created / mounted / updated / destroyedの使い方)
- $nextTickの使い方(ライフサイクルフック)
- メソッドの定義方法
- エラー一覧
- ルーティング設定
- aリンクの貼り方と動的URLの作成
- Mixinを利用した共通処理の記述方法
- v-bindによるデータ連携
- ヘッダー/フッターの共通コンポーネント
- ナビゲーションの現在ページをハイライトする方法
- 画面サイズの取得方法
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- IPv6とは|128bitアドレス・コロン16進表記/::省略・リンクローカル・SLAAC・デュアルスタック NEW 2026-06-22 12:34:44
- MAC アドレスフィルタリングの仕組みと限界 | ネットワーク入門 NEW 2026-06-22 12:19:10
- VPNとは|暗号トンネル・サイト間/リモートアクセス・IPsec/SSL-VPN/WireGuardを解説 NEW 2026-06-22 12:19:10
- WebSocket とは 全二重リアルタイム通信 ws/wss | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/2 とは 多重化・HPACK・バイナリフレーム | ネットワーク入門 NEW 2026-06-22 12:17:25
- Web通信プロトコル入門 HTTP/2・HTTP/3・WebSocket・gRPC・WebRTC | ネットワーク入門 NEW 2026-06-22 12:17:25
- gRPC とは HTTP/2 + Protocol Buffers の高速 RPC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/3 (QUIC) とは UDP ベースの低遅延 Web 通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebRTC とは ブラウザ間 P2P の音声・映像・データ通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- 証明書と認証局(CA)とは|X.509・信頼チェーン・DV/OV/EV・失効(CRL/OCSP)を解説 NEW 2026-06-22 12:17:24
- ファイアウォールとは|パケットフィルタ・ステートフル・DMZ・次世代FW(L4/L7)を解説 NEW 2026-06-22 12:17:24
- iptables/nftablesとは|テーブル・チェーン・ルール例・永続化をLinux視点で解説 NEW 2026-06-22 12:17:24
- HAProxy とは frontend/backend と設定例 | ネットワーク入門 NEW 2026-06-22 12:17:24
- TLS/SSLの仕組み|ハンドシェイク・暗号スイート・前方秘匿性・証明書検証をわかりやすく解説 NEW 2026-06-22 12:17:24
- CDN とは エッジキャッシュ・TTL・Cloudflare/CloudFront | ネットワーク入門 NEW 2026-06-22 12:17:24
コメントを削除してもよろしいでしょうか?