动态路由
有的时候,我们需要把满足某种规则的路由全部匹配到同一个组件,比如不同的商品的 url
/item/1
/item/2
/item/3
...
我们不可能为每一个商品都定义一个独立的组件,而是把它们都映射到同一个组件,同时 url 后面的部分为动态变化的部分,我们会在设计路由的时候进行特殊的处理
...
{
path: '/item/:id',
name: 'item',
component: Item
}
...
动态路由就是通过url路径部分带数据发送请求,vue会监听到数据的变化,数据变化时就会去找匹配的组件,然后进行解析。
其中 :itemId
表示匹配的 url 中动态部分内容,如上面的 1,2,3 等,同时该值将被赋值给路由的变量 itemId
url可以使用拼接方式,也可以使用动态路由绑定
// home.vue
<template>
<div class="home">
<h2>商品列表——首页</h2>
<ul class="item-list">
<li class="head">
<span>名称</span>
<span>品牌</span>
<span>价格</span>
<span>操作</span>
</li>
<li v-for="item of items" :key="item.id">
<span>{{item.name}}</span>
<span>{{item.vendor}}</span>
<span>{{item.price|RMB}}</span>
<span>
<!-- 注意:用v-bind方式,则属性值里必须是表达式-->
<!-- <router-link :to="`/item/${item.id}`">查看详情</router-link> -->
<!-- 以动态路由形式赋值,注意一定要以v-bind形式进行绑定,后台路由需要设置name:'item' -->
<router-link :to="{name: 'item', params:{id: item.id}}">查看详情</router-link>
</span>
</li>
</ul>
</div>
</template>
<script>
import axios from 'axios';
import {RMB} from '@/filters/RMB';
export default {
name: 'home',
data() {
return {
items: []
}
},
filters: {
RMB
},
created() {
axios({
url: '/api/items'
}).then(res => {
this.items = res.data;
});
}
}
</script>
<style>
ul {
margin: 0;
padding: 0;
}
li {
list-style: none;
}
.item-list li {
padding: 10px;
display: flex;
justify-content: space-between;
height: 30px;
line-height: 30px;
border-bottom: 1px dotted #333;
}
.item-list li.head {
font-weight: bold;
}
.item-list li span {
min-width: 200px;
}
</style>
一、路由对象
vue-router 会在组件中添加(注入)两个属性
-
$router
-
$route
1.1 $router对象
该对象其实就是 new VueRouter(...) 返回的路由对象,通过该对象我们可以访问全局路由信息,调用路由下的方法,比如:go
、back
、push
等
// 使用watch监听组件变化,注意watch是对象
watch: {
sort() {
// 监听到sort发生变化后重新发起请求(但是这样不会在url上带上sort=desc不利于分享状态)
// await this.getItems();
// 然后通过编程式导航进行跳转(可以拼接字符串,也可以对象形式传参)
// this.$router.push('/?sort=' + this.sort);
this.$router.push({
// 此处name对应路由中Home组件的路由name
name: "home",
// 此处为地址栏上地址加上queryString
query: {
sort: this.sort
}
});
}
1.2 $route对象
通过该对象可以访问与当前路由匹配的信息
1.2.1 $route.params
获取动态路由有关的信息
如,从主页跳转到商品详情页后,通过路由地址中的商品id获取商品详情并展示。
//item.vue
<template>
<div>
<template v-if="item">
<h2>商品详情 - {{item.name}}</h2>
<dt>ID</dt>
<dd>{{item.id}}</dd>
<dt>名称</dt>
<dd>{{item.name}}</dd>
<dt>价格</dt>
<dd>{{item.price|RMB}}</dd>
</template>
<template v-else>
<h2>没有该商品信息</h2>
</template>
</div>
</template>
<script>
import axios from "axios";
import RMB from "@/filter/RMB";
export default {
name: "Item",
// 注册过滤器
filters: {
RMB
},
data() {
return {
item:null
};
},
created() {
// 通过动态路由和拼接字符串形式都需要通过 路由对象 获取id的值
const {id} = this.$route.params;
axios({
// 详情页:id占位符
// url: "/api/item/"+id
url: `/api/item/${id}`
}).then(res => {
this.item = res.data;
});
}
};
</script>
<style>
</style>