雖然我們可以使用 this.$route
去存取目前 Route,但開發 Component 時,你無法確認 User 是否使用 Vue Router,畢竟 Vue Router 是選配,也無法確認會用什麼 Params 或 Query String,比較好的方式還是回歸 Component 正統設計方式:使用 Props。
Version
macOS Mojave 10.14.5
Node 12.4.0
Vue CLI 3.8.4
Vue 2.6.10
$route
- 當網址為
/products/1
時 - 顯示
Product
component 的T-Shirts
router.js
import Vue from 'vue';
import Router from 'vue-router';
import Home from './views/Home.vue';
Vue.use(Router);
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/about',
name: 'about',
component: () => import(/* webpackChunkName: "about" */ './views/About.vue')
},
{
path: '/products/:id?',
name: 'products',
component: () => import(/* webpackChunkName: "products" */ './views/Products.vue'),
},
]
});
19 行
{
path: '/products/:id?',
name: 'products',
component: () => import(/* webpackChunkName: "products" */ './views/Products.vue'),
}
path 使用 id
param。
Product.vue
<template>
<div>
<h1>Products</h1>
<h2>{{ product }}</h2>
</div>
</template>
<script>
let products = {
0: 'Shoes',
1: 'T-Shirts',
2: 'Pants',
};
let product = function() {
return products[this.$route.params.id] || 'N/A';
};
export default {
name: 'Products',
computed: {
product,
},
};
</script>
15 行
let product = function() {
return products[this.$route.params.id] || 'N/A';
};
需使用 this.$route
存取 route,也就是 component 與 Vue Router 耦合。
以 component 角度,並不確定 user 一定有使用 Vue Router,也不確定是否使用 params 傳進資料,若 component 這樣寫,重複使用程度就很低,比較好的方式是改用 props。
By Boolean
router.js
{
path: '/products/:id?',
name: 'products',
component: () => import(/* webpackChunkName: "products" */ './views/Products.vue'),
props: true,
},
path
寫法不變,加上 props: true
,表示 Vue Router 會將 id
以 props 傳進 products
component。
Products.vue
<template>
<div>
<h1>Products</h1>
<h2>{{ product }}</h2>
</div>
</template>
<script>
let products = {
0: 'Shoes',
1: 'T-Shirts',
2: 'Pants',
};
let product = function() {
return products[this.id] || 'N/A';
};
export default {
name: 'Products',
props: [
'id'
],
computed: {
product,
},
};
</script>
21 行
props: [
'id'
],
新增 id
props。
15 行
let product = function() {
return products[this.id] || 'N/A';
};
由原本的 this.$route.params.id
改成 this.id
。
其中 id
是 props, component 就不跟 Vue Router 耦合了。
By Object
router.js
{
path: '/products/:id?',
name: 'products',
component: () => import(/* webpackChunkName: "products" */ './views/Products.vue'),
props: { id: 1 },
},
props
property 改傳入 object,id
為 props。
若想由
router.js
傳入固定值給 component,這是個好方法
Product.vue
寫法不變。
By Function
router.js
{
path: '/products/:id?',
name: 'products',
component: () => import(/* webpackChunkName: "products" */ './views/Products.vue'),
props: route => ({ id: route.params.id }),
},
Props
也可使用 function,傳入 route,回傳 object,直接對 props 操作。
這種寫法最靈活,若要在
router.js
傳入的 props 有邏輯,則建議使用此方法
Conclusion
- Vue Router 支援 component 的 props,除了最基本的 boolean 外,還支援了 object 與 function
- By object 可讓我們在 router 自行傳入資料客製化 component
- By function 則最靈活,我們可直接在 arrow function 寫邏輯改變要傳入的 props,甚至搭配 higher order function 與 closure 產生 props
Sample Code
完整範例可在我的 GitHub 上找到