vue-router
- 官方提供的用来实现 SPA 的 vue 插件
- github: https://github.com/vuejs/vue-router
- 中文文档: http://router.vuejs.org/zh-cn/
- 下载: npm install vue-router --save
相关 API 说明
-
VueRouter()
: 用于创建路由器的构建函数
new VueRouter({
// 多个配置项
})
- 路由配置
routes: [
{ // 一般路由
path: '/about',
component: About
},
{ // 自动跳转路由
path: '/',
redirect: '/about'
}
]
- 注册路由器
import router from './router'
new Vue({
router
})
- 使用路由组件标签
<router-link>
: 用来生成路由链接
<router-link to="/xxx">Go to XXX</router-link>
<router-view>
: 用来显示当前路由组件界面
<router-view></router-view>
路由组件
- Home.vue
- About.vue
应用组件: App.vue
<div>
<!--路由链接-->
<router-link to="/about">About</router-link>
<router-link to="/home">Home</router-link>
<!--用于渲染当前路由组件-->
<router-view></router-view>
</div>
路由器模块: src/router/index.js
export default new VueRouter({
routes: [
{
path: '/',
redirect: '/about'
},
{
path: '/about',
component: About
},
{
path: '/home',
component: Home
}
]
})
注册路由器: main.js
import Vue from 'vue'
import router from './router'
// 创建 vue 配置路由器
new Vue({
el: '#app',
router,
render: h => h(app)
})
优化路由器配置
linkActiveClass: 'active'
, // 指定选中的路由链接的 class
总结: 编写使用路由的 3 步
- 定义路由组件
- 注册路由
- 使用路由
<router-link>
<router-view>
嵌套路由
子路由组件
- News.vue
- Message.vue
配置嵌套路由: router.js
path: '/home',
component: home,
children: [
{
path: 'news',
component: News
},
{
path: 'message',
component: Message
}
]
路由链接: Home.vue
<router-link to="/home/news">News</router-link>
<router-link to="/home/message">Message</router-link>
<router-view></route-view>
向路由组件传递数据
- 方式 1: 路由路径携带参数(param/query)
配置路由
children: [
{
path: 'mdetail/:id',
component: MessageDetail
}
]
路由路径
<router-link :to="'/home/message/mdetail/'+m.id">{{m.title}}</router-link>
路由组件中读取请求参数
this.$route.params.id
- 方式 2: <router-view>属性携带数据
<router-view :msg="msg"></router-view>
缓存路由组件对象
- 默认情况下, 被切换的路由组件对象会死亡释放, 再次回来时是重新创建的
- 如果可以缓存路由组件对象, 可以提高用户体验
编码
<keep-alive>
<router-view></router-view>
</keep-alive>
编程式路由导航
- this.$router.push(path): 相当于点击路由链接(可以返回到当前路由界面)
- this.$router.replace(path): 用新路由替换当前路由(不可以返回到当前路由界面)
- this.$router.back(): 请求(返回)上一个记录路由
- this.$router.go(-1): 请求(返回)上一个记录路由
- this.$router.go(1): 请求下一个记录路由
完整示例代码
/*index.js*/
/*
路由器对象模块
*/
import Vue from 'vue'
import VueRouter from 'vue-router'
import About from '../pages/About.vue'
import Home from '../pages/Home.vue'
import News from '../pages/News.vue'
import Message from '../pages/Message.vue'
import MessageDetail from '../pages/MessageDetail.vue'
// 声明使用vue-router插件
/*
内部定义并注册了2个组件标签(router-link/router-view),
给组件对象添加了2个属性:
1. $router: 路由器
2. $route: 当前路由
*/
Vue.use(VueRouter)
export default new VueRouter ({
// 注册应用中所有的路由
routes: [
{
path: '/about',
component: About
},
{
path: '/home',
component: Home,
children: [
{
path: '/home/news',
component: News
},
{
path: 'message',
component: Message,
children: [
{
path:'detail/:id',
component: MessageDetail
}
]
},
{
path: '',
redirect: '/home/news'
}
]
},
{
path: '/',
redirect: '/about'
}
]
})
/*main.js*/
/*
入口JS
*/
import Vue from 'vue'
import App from './App.vue'
import router from './router'
/* eslint-disable no-new */
new Vue({
el: '#app',
components: {App}, // 映射组件标签
template: '<App/>', // 指定需要渲染到页面的模板
router // 注册路由器
})
/* App.vue*/
<template>
<div>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header"><h2>Router Test</h2></div>
</div>
</div>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<!--生成路由链接-->
<router-link to="/about" class="list-group-item">About</router-link>
<router-link to="/home" class="list-group-item">Home</router-link>
</div>
</div>
<div class="col-xs-6">
<div class="panel">
<div class="panel-body">
<!--显示当前组件-->
<keep-alive>
<router-view msg="abc"></router-view>
</keep-alive>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {}
</script>
<style>
</style>
/*About.vue*/
<template>
<div>
<h2>About</h2>
<p>{{msg}}</p>
<input type="text">
</div>
</template>
<script>
export default {
props: {
msg: String
}
}
</script>
<style>
</style>
/*home.vue*/
<template>
<div>
<h2>Home</h2>
<div>
<ul class="nav nav-tabs">
<li><router-link to="/home/news">News</router-link></li>
<li><router-link to="/home/message">Message</router-link></li>
</ul>
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {}
</script>
<style>
</style>
/*Message.vue*/
<template>
<div>
<ul>
<li v-for="m in messages" :key="m.id">
<router-link :to="`/home/message/detail/${m.id}`">{{m.title}}</router-link>
<button @click="pushShow(m.id)">push查看</button>
<button @click="replaceShow(m.id)">replace查看</button>
</li>
</ul>
<button @click="$router.back()">回退</button>
<hr>
<router-view></router-view>
</div>
</template>
<script>
export default {
data () {
return {
messages: [
/* {id: 1, title: 'Message001'},
{id: 3, title: 'Message003'},
{id: 5, title: 'Message005'}*/
]
}
},
mounted () {
setTimeout(() => {
const messages = [
{id: 1, title: 'Message001'},
{id: 3, title: 'Message003'},
{id: 5, title: 'Message005'}
]
this.messages = messages
}, 1000)
},
methods: {
pushShow (id) {
this.$router.push(`/home/message/detail/${id}`)
},
replaceShow(id) {
this.$router.replace(`/home/message/detail/${id}`)
}
}
}
</script>
<style>
</style>
/*MessageDetail.vue*/
<template>
<ul>
<li>id: {{$route.params.id}}</li>
<li>title: {{detail.title}}</li>
<li>content: {{detail.content}}</li>
</ul>
</template>
<script>
const messageDetails = [
{id: 1, title: 'Message001', content: 'message content00111....'},
{id: 3, title: 'Message003', content: 'message content00222....'},
{id: 5, title: 'Message005', content: 'message content00333....'}
]
export default {
data() {
return {
detail: {}
}
},
mounted () {// 改变当前路由组件参数数据时, 不会重新创建组件对象, mounted不会重新执行
const id = this.$route.params.id
this.detail = messageDetails.find(detail => detail.id===id*1)
},
watch: {
$route: function () { // 改变当前路由组件参数数据时自动调用
console.log('$route()')
const id = this.$route.params.id
this.detail = messageDetails.find(detail => detail.id===id*1)
}
}
}
</script>
<style>
</style>
/*News.vue*/
<template>
<ul>
<li v-for="(news, index) in newsArr" :key="index">{{news}}</li>
</ul>
</template>
<script>
export default {
data () {
return {
newsArr: ['News001', 'News002', 'News003']
}
}
}
</script>
<style>
</style>
网友评论