昨天有提到的路由今天要來做拆解,做更深入的了解。昨天提到的router/index.js設定也可以寫成像書中的方式,裡面有兩個今天要研究的重點history
和routes
。
import { createRouter, createWebHistory } from 'vue-router'
import Home from './views/Home.vue'
import About from './views/About.vue'
export const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: Home },
{ path: '/about', component: About },
],
});
安裝的時候有問說要不要採用history mode
就是指這裡!! 他有兩種不同的方式,分別為Hash Mode
與HTML5 (History API) Mode
。
顧名思義就是利用#
做頁面的切換,history
設定成createWebHashHistory
就可以開始Hash模式,預設路徑為location.pathname
或/
根目錄,想另外加路徑的話可以createWebHashHistory('/folder/')
處理,得出的就會是https://example.com/folder/#
。
缺點: 搜尋引擎會忽略#
,不利於SEO
export const router = createRouter({
history: createWebHashHistory(),
routes: [
...,
],
});
使用此模式實現轉跳頁面不需要重新載入頁面,此外沒有#的url,如https://example.com/folder
,但這模式必須搭配後端路由,不然當使用者用http://oursite.com/folder
就會出現404錯誤頁面了。(btw加路徑的方式和Hash模式一樣)
export const router = createRouter({
history: createWebHistory(),
routes: [
...,
],
});
用一開始製作的範例來說明(顏色框代表同一區),http://localhost:8081/
下會放入Home
元件,也就是說path:'/About'
時會使用About
元件。
使不同的path指向同一個component。資料夾內容如下
step1 : main.js進入點
import { createApp } from 'vue'
import App from './App.vue'
import { router } from './router'
const app = createApp(App).use(router)
app.mount('#app')
step2 : App.vue中用v-for的方式做出五個link
<template>
<ul>
<li v-for="i in 5" :key="i">
<router-link :to="`/users/${i}`"> /users/{{ i }} </router-link>
</li>
</ul>
<router-view></router-view>
</template>
step3 : router.js設定路徑。使用:
符號就可以將userId傳入User元件,User元件也可以利用this.$route.params.userId
取得參數($route
這部分官方文件有其他用法與說明)
import { createRouter, createWebHistory } from "vue-router";
import User from "./views/User.vue";
export const router = createRouter({
history: createWebHistory(),
routes: [{ path: "/users/:userId", component: User }]
});
step4 : User.vue元件將取地的參數做處理,透過watch監測userId的更新還重新渲染相對應的資料
<template>
<h1>UserID: {{ $route.params.userId }}</h1>
<pre>{{ userInfo }}</pre>
</template>
<script>
export default {
data() {
return {
userInfo: {},
};
},
computed: {
userId() {
return this.$route.params.userId;
},
},
watch: {
userId: async function (val) {
this.userInfo = await this.fetchUserInfo(val);
},
},
methods: {
async fetchUserInfo(id) {
return await fetch("https://jsonplaceholder.typicode.com/users/" + id)
.then((response) => response.json())
.then((json) => json);
},
},
async created() {
this.userInfo = await this.fetchUserInfo(this.userId);
},
};
</script>
可以利用正規表達式(Regexp)自定義傳遞
const routes = [
// /:orderId -> 只能是數字
{ path: '/:orderId(\\d+)' },
// /:productName -> 無限制
{ path: '/:productName' },
]
如果讀取到不存在的URL可以用/:pathMatch(.*)*
來讓所有路由連到此元件
const routes = [
// will match everything and put it under `$route.params.pathMatch`
{ path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
// will match anything starting with `/user-` and put it under `$route.params.afterUser`
{ path: '/user-:afterUser(.*)', component: UserGeneric },
]
?
可以讓使/users
或/users/xxx
都會被帶到指定的元件。
const routes = [
// will match /users and /users/posva
{ path: '/users/:userId?' },
// will match /users and /users/42
{ path: '/users/:userId(\\d+)?' },
]