在實務上 Route 也會如 RESTful API 一樣,動態在 Route 中夾帶 Data,此時可使用 Dynamic Route Matching,而不用將 Route 寫死。
Version
Vue 3.0.11
Vue Router 4.0.6
Dynamic Router Matching
Data 以 route 形式傳入並在 HTML 顯示。
router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '/src/components/Home.vue'
import About from '/src/components/About.vue'
import Product from '/src/components/Products.vue'
let history = createWebHistory()
let routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
},
{
path: '/products/:name',
name: 'Product',
component: Product
}
]
export default createRouter({ history, routes })
18 行
{
path: '/products/:name',
name: 'Product',
component: Product
}
在 path
加上 /products/:name
,其中 name
為 param,前面加上 :
。
Component
Products.vue
<template lang='pug'>
div {{ name }}
</template>
<script setup>
import { useRoute } from 'vue-router'
let { params: { name }} = useRoute()
</script>
第 8 行
let { params: { name }} = useRoute()
從 useRoute()
destructure 出 name
。
router-link
以 <router-link>
使用 dynamic router matching。
App.vue
<template lang='pug'>
RouterLink(:to='{ name: "Product", params: { name: "apple" }}') Product
RouterView/
</template>
若使用 RouterLink
,則需加上 params
,並傳入包含參數名稱的 Object。
<template lang='pug'>
RouterLink(:to='{ name: "Product", params: { name }}') Product
RouterView/
</template>
<script setup>
ref: name = 'apple'
</script>
也可使用 data binding 將 state 綁定到 params
。
Router.push()
以 Router.push()
使用 dynamic router matching。
<template lang='pug'>
a(@click='onClick', href='#') Product
router-view/
</template>
<script setup>
import { useRouter } from 'vue-router'
let { push } = useRouter()
ref: name = 'apple'
let onClick = () => push({ name: 'Product', params: { name }})
</script>
第 9 行
let { push } = useRouter()
從 useRouter()
destructure 出 push()
。
12 行
let onClick = () => push({ name: 'Product', params: { name }})
使用 push()
跳轉網頁,以 params
傳入包含參數名稱的 Object。
Point-free
以 Point-free 使用 dynamic router matching。
always()
<template lang='pug'>
a(@click='onClick', href='#') Product
router-view/
</template>
<script setup>
import { useRouter } from 'vue-router'
import { pipe, always } from 'ramda'
let { push } = useRouter()
ref: name = 'apple'
let onClick = pipe(
always({ name: 'Product', params: { name }}),
push
)
</script>
14 行
let onClick = pipe(
always({ name: 'Product', params: { name }}),
push
)
使用 pipe()
組合出 onClick()
:
always({ name: 'Product', params: { name }})
:準備 argumentpush
:跳轉到指定 name
thunkify()
<template lang='pug'>
a(@click='onClick', href='#') Product
router-view/
</template>
<script setup>
import { useRouter } from 'vue-router'
import { thunkify } from 'ramda'
let { push } = useRouter()
ref: name = 'apple'
let onClick = thunkify(push)({ name: 'Product', params: { name }})
</script>
14 行
let onClick = thunkify(push)({ name: 'Product', params: { name }})
使用 thunkify()
組合出 onClick()
:
thunkify(push)
:將push()
delay 一個 argument 再傳入
Conclusion
- Dynamic route matching 讓我們不用將 route 寫死,只要符合特定格式,就可以搭配特定 component
- Vue router 4 提供了
useRoute()
與useRouter()
更適合 Composition API 使用