
Vue.jsのmethods, computed, watch 演習
methods, computed, watchの違い Vue.jsには状態の扱い方として methods 、 computed 、 watch の3つの主要な […]
npm install vue-router
createRouter()
app.use(router)
router.beforeEach
beforeEnter
beforeRouteEnter
, beforeRouteUpdate
, beforeRouteLeave
path: '/user/:id'
$route.params.id
または Composition APIの useRoute()
path: '/:pathMatch(.*)*'
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
<template>
<nav>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</nav>
<router-view/>
</template>
methods: {
goToAbout() {
this.$router.push('/about')
// または
this.$router.push({ name: 'About' })
}
}
router.beforeEach((to, from, next) => {
console.log(`Navigation to: ${to.path}`)
next() // 必ずnext()を呼び出す
})
{
path: '/dashboard',
component: Dashboard,
beforeEnter: (to, from, next) => {
if (!localStorage.getItem('authToken')) {
next('/login')
} else {
next()
}
}
}
{
path: '/user/:userId',
name: 'UserProfile',
component: UserProfile
}
// コンポーネント内でアクセス
this.$route.params.userId
// Composition APIでは
import { useRoute } from 'vue-router'
const route = useRoute()
const userId = route.params.userId
{
path: '/dashboard',
component: DashboardLayout,
children: [
{
path: '',
component: DashboardHome
},
{
path: 'settings',
component: DashboardSettings
}
]
}
<router-link :to="{ name: 'UserProfile', params: { userId: 123 } }">
プロフィール
</router-link>
<!-- プログラム的ナビゲーション -->
<script>
this.$router.push({
name: 'UserProfile',
params: { userId: 123 }
})
</script>
{
path: '/multi-view',
components: {
default: MainContent,
sidebar: Sidebar,
header: AppHeader
}
}
<router-view name="header"/>
<router-view name="sidebar"/>
<router-view/>
const router = createRouter({
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else if (to.hash) {
return { selector: to.hash }
} else {
return { top: 0 }
}
}
})
router.beforeEach((to, from, next) => {
const isAuthenticated = checkAuth()
if (to.meta.requiresAuth && !isAuthenticated) {
next('/login')
} else {
next()
}
})
// ログインページ
methods: {
login() {
// 認証処理...
const redirect = this.$route.query.redirect || '/'
this.$router.push(redirect)
}
}
{
path: '/admin',
component: AdminPanel,
meta: { requiresAdmin: true }
}
// ガード内でチェック
if (to.meta.requiresAdmin && !user.isAdmin) {
next('/access-denied')
}
beforeRouteLeave(to, from, next) {
if (this.hasUnsavedChanges) {
const confirm = window.confirm('変更が保存されていません。離れますか?')
if (confirm) next()
else next(false)
} else {
next()
}
}
{
path: '/product/:category/:id',
component: ProductDetail
}
// アクセス例
this.$router.push('/product/electronics/123')
{
path: '/user/:id(\\d+)', // 数値のみ許可
component: UserDetail
}
{
path: '/admin',
component: () => import('../views/Admin.vue')
}
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
component: NotFound
}
<router-view v-slot="{ Component }">
<transition name="fade" mode="out-in">
<component :is="Component" />
</transition>
</router-view>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.3s ease;
}
.fade-enter-from, .fade-leave-to {
opacity: 0;
}
</style>
// ルート定義
{
path: '/admin',
meta: { permissions: ['ADMIN'] }
}
// ガード
router.beforeEach((to, from, next) => {
const requiredPermissions = to.meta.permissions
if (requiredPermissions) {
const hasPermission = checkUserPermissions(requiredPermissions)
if (!hasPermission) next('/forbidden')
}
next()
})
<router-link
v-for="tab in tabs"
:key="tab.path"
:to="tab.path"
active-class="active-tab"
>
{{ tab.name }}
</router-link>
<router-view />
const routeHistory = []
router.afterEach((to) => {
routeHistory.push({
path: to.path,
timestamp: new Date()
})
})
// 分析
function getFrequentRoutes() {
const counts = {}
routeHistory.forEach(route => {
counts[route.path] = (counts[route.path] || 0) + 1
})
return Object.entries(counts).sort((a, b) => b[1] - a[1])
}
// Nuxt.jsのasyncData
export default {
async asyncData({ params }) {
const post = await fetchPost(params.id)
return { post }
}
}
// メインアプリ
{
path: '/app1/*',
component: MicroAppContainer,
meta: { appName: 'app1' }
}
// コンテナコンポーネント
mounted() {
loadMicroApp(this.$route.meta.appName)
}
これらの解答例は、Vue Routerの基本から高度なユースケースまでを網羅しています。実際のプロジェクトで遭遇する様々なシナリオに対応できるよう、段階的に学習できる構成になっています。