vue-router
动态路由
有的时候,我们需要把满足某种规则的路由全部匹配到同一个组件,比如不同的商品的 url
/item/1
/item/2
/item/3
...
我们不可能为每一个商品都定义一个独立的组件,而是把它们都映射到同一个组件,同时 url 后面的部分为动态变化的部分,我们会在设计路由的时候进行特殊的处理
...
{
path: '/item/:itemId',
name: 'item',
component: Item
}
...
其中 :itemId
表示匹配的 url 中动态部分内容,如上面的 1,2,3 等,同时该值将被赋值给路由的变量 itemId
// home.vue
<template>
<div class="home">
<h2>商品列表</h2>
<ul class="item-list">
<li class="head">
<span>名称</span>
<span>价格</span>
<span>操作</span>
</li>
<li v-for="item of items" :key="item.id">
<span>
<router-link :to='{name: "item", params:{itemId: item.id}}'>{{item.name}}</router-link>
</span>
<span>{{item.price|RMB}}</span>
<span>
<button>添加到购物车</button>
</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
$router 对象(全局)
该对象其实就是 new VueRouter(…) 得到的路由对象,通过该对象我们可以访问全局路由信息,调用路由下的方法,比如:go
、back
、push
等
$router其实是一个Vue-router实例/类。其实就是整个应用的路由信息
$route 对象(当前)
通过该对象可以访问与当前路由匹配的信息
是当前匹配的路由对象:根据当前访问的地址和根据当前地址生成的对象而生成的对象
$route.params
获取动态路由有关的信息
注意template里面的逻辑!!!一开始页面加载时,error=false,进入v-else的template,且item还没出来,进入第二个v-else,此时显示“Loading…”,页面数据请求到时,data()刷新,数据重新渲染,有请求到数据,进入v-else的v-if显示商品详情,没有请求到数据,在try…catch的catch中修改error,数据重新渲染,进入第一个v-if显示没有商品信息
<template>
<div>
<template v-if="error">
没有该商品信息
</template>
<template v-else>
<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>
Loading...
</template>
</template>
</div>
</template>
<script>
import axios from 'axios';
import RMB from '@/filters/RMB';
import ca from "../../../../../2020-04-09(vue05)/源码/element-dev/src/locale/lang/ca";
export default {
name: 'Item',
data() {
return {
item: null,
error: false
}
},
filters: {
RMB
},
async created() {
// this.$router : 整个应用的路由信息 VueRouter 对象
// this.$route : 当前匹配的路由对象
// console.log(this.$router, this.$route);
let itemId = this.$route.params.itemId;
try {
let rs = await axios({
url: '/api/item/' + itemId
});
this.item = rs.data;
} catch(e) {
this.error =true;
}
}
}
</script>