在原先的router-view
中再放一個router-view
。
接續前一個案例,User.vue中放一個router-view給等一下要新增的Poster.vue
<template>
<h1>User: {{ userId }} - {{ userInfo?.name }}</h1>
<div>username: @{{ userInfo.username }}</div>
<div>email: {{ userInfo.email }}</div>
<div>phone: {{ userInfo.phone }}</div>
<hr />
Show
<router-link :to="`/users/${userId}/posts`">
/users/{{ userId }}/posts
</router-link>
<hr />
<router-view></router-view>
</template>
接著,新增view/Post.vue
<template>
<h1>Post from User-{{ userId }}</h1>
<ol>
<li v-for="post in posts" :key="post.id">
<h3>{{ post.title }}</h3>
<p>{{ post.body }}</p>
</li>
</ol>
</template>
<script>
export default {
data() {
return {
posts: [],
};
},
computed: {
userId() {
return this.$route.params.userId;
},
},
methods: {
async fetchUserPosts() {
return await fetch(
"https://jsonplaceholder.typicode.com/posts?userId=" + this.userId
).then((response) => response.json());
},
},
async created() {
this.posts = await this.fetchUserPosts(this.userId);
},
};
</script>
最後,修改router.js
,引入Post.vue
,並在routes
之下建立一個children
import { createRouter, createWebHistory } from "vue-router";
import User from "./views/User.vue";
import Post from "./views/Post.vue";
export const router = createRouter({
history: createWebHistory(),
routes: [
{
path: "/users/:userId",
component: User,
children: [
{
path: "posts",
component: Post
}
]
}
]
});
畫面中可以看到原先的http://localhost:8080/users/5
在點擊Show /users/5/posts
後會變成http://localhost:8080/users/5/posts
,這就是巢狀的效果。
除了用path指定路徑,還可以用name更直覺式的設定路徑。
routes: [
{ path: '/', name: 'home', component: Home },
{ path: '/foo', name: 'foo', component: Foo },
{ path: '/bar/:id', name: 'bar', component: Bar }
]
router-link就可以使用name設定to
<ul>
<li><router-link :to="{ name: 'home' }">home</router-link></li>
<li><router-link :to="{ name: 'foo' }">foo</router-link></li>
<li><router-link :to="{ name: 'bar', params: { id: 123 }}">bar</router-link></li>
</ul>
//result: /,/foo,/bar123
如書中的解釋圖,子層元件中可能也會有很多個router-view,具名方式和剛剛的差不多。
給予一個name
屬性,並在routes
中新增一個components
屬性在children
裡面。
<!-- Page.vue -->
<div> <router-view class="view nav-block" name="Nav">
</router-view> <router-view class="view header-block" name="Header">
</router-view> <router-view class="view body-block"></router-view> </div>
import Page from './page.vue';
import Body from './body.vue';
import Header from './header.vue';
import Nav from './nav.vue';
const routes = [
{ path: '/pages',
component: Page,
children: [
components: {
default: Body,
Header: Header,
Nav: Nav,
},
]
}
];
使用redirect選項指定某個路由要轉址到某個目標。
const routes = [
//方法一: 直接使用 /home --> /
{ path: '/home', redirect: '/' },
//方法二: 使用name /app --> appPage
{ path: '/app', redirect: { name: 'appPage' } },
//方法三: 使用function /search/screens --> /search?q=screens
{ path: '/search/:searchText', redirect: to => {
return { path: '/search', query: { q: to.params.searchText } }
},
},
]
與redirect
功能很像的alias
,在點擊path
為/
的情況下依舊保持/home
的樣子,不會強制轉到/
。
const routes = [
//單一別名
{ path: '/',
component: Homepage,
alias: '/home' },
//多個別名
{ path: '/users',
component: UsersLayout,
children: [
// result : - /users // - /users/list // - /people
{ path: '',
component: UserList,
alias: ['/people', 'list']
},
],
//也可以加上參數(path與alias需保持一致)
{ path: '/users/:id',
component: UsersByIdLayout,
children: [
// result : - /users/24 // - /users/24/profile // - /24
{ path: 'profile',
component: UserDetails,
alias: ['/:id', '']
},
],
},
]
如官方文件所說,routes
和元件的緊密性使的元件不能彈性的重複使用,元件若沒有Vue Router的情況下$route.params.id
就沒有辦法使用。
//component
const User = {
template: '<div>User {{ $route.params.id }}</div>'
}
//routes
const router = new VueRouter({
routes: [{ path: '/user/:id', component: User }]
})
所以衍生出props
用法,這樣:id
的屬性就可以傳入元件使用,達到重複利用的功能。
//component
const User = {
props:['id'],
template: '<div>User {{ id }}</div>'
}
//routes
const router = new VueRouter({
routes: [{ path: '/user/:id', component: User, props:true }]
})
若是具名路由,則需要一個個指定props
const router = new VueRouter({
routes: [
//1. boolean樣式
{ path: '/user/:id', component: User, props: true },
//2. 物件樣式
{ path: '/promotion/from-newsletter',
component: Promotion,
props: { newsletterPopup: false }
}
//3. funciton樣式
{
path: '/user/:id',
components: {
default: User,
sidebar: Sidebar
},
props: {
default: true,
sidebar: route => ({ search: route.query.q })
}
}
]
})
HTML5 History 模式
https://router.vuejs.org/zh/guide/essentials/history-mode.html#后端配置例子
Vue Router – History mode, Catch all/404, Matching Syntax
https://jungtin.me/vue-router-history-mode-catch-all-404-matching-syntax/#ib-toc-anchor-1
[Vue.js] 筆記 - Vue-Route
https://dotblogs.com.tw/Null/2020/05/12/221249
[Vue] 跟著 Vue 闖盪前端世界 - 08 網站路由 vue-router
https://dotblogs.com.tw/wasichris/2017/03/06/235449
Vue Router
https://linwei5316.medium.com/vue-router-4c2aad1cc352