对于大多数单页面应用,都推荐使用官方支持的 vue-router 库。下面的代码默认导入了vue-router 库
路由的基本使用
在Vue中,使用new VueRouter来创建一个路由,在Vue实例中将该路由放入Vue实例中的myRouter,即在某个实例上创建了一个路由。
let login = {
template: '<h1>this is login</h1>'
}
let myRouter = new VueRouter({
routes: [{
path: '/login',
component: login
}]
})
let vm = new Vue({
el: '#app',
data: {},
methods: {},
router: myRouter
})
在该实例所对应的html元素中,使用<router-view></router-view>可以用来显示路由对应的模板,根据上面的代码,当hash为/login时就会显示login模板中的内容,html代码如下
<div id="app">
<router-view></router-view>
</div>
渲染后为
<div id="app">
<h1>this is login</h1>
</div>
路由的切换
路由可以通过router-link标签的to属性来切换,to属性的值为要切换到的hash。
<div id="app">
<router-link to="/login">login</router-link>
<router-link to="/register">register</router-link>
<router-view></router-view>
</div>
<script>
let login = {
template: '<h1>this is login</h1>'
}
let register = {
template: '<h1>this is register</h1>'
}
let myRouter = new VueRouter({
routes: [{
path: '/login',
component: login
}, {
path: '/register',
component: register
}]
})
let vm = new Vue({
el: '#app',
data: {},
methods: {},
router: myRouter
})
</script>
页面渲染为下
<div id="app">
<a href="#/login" class="">login</a>
<a href="#/register" class="">register</a>
<!---->
</div>
当点击login时就会显示hash为/login路由的模板,而点击register时就会显示hash为/register路由的模板。点击后为下
// 点击login
<div id="app">
<a href="#/login" class="router-link-exact-active router-link-active">login</a>
<a href="#/register" class="">register</a>
<h1>this is login</h1>
</div>
// 点击register
<div id="app">
<a href="#/login" class="">login</a>
<a href="#/register" class="router-link-exact-active router-link-active">register</a>
<h1>this is register</h1>
</div>
切换的标签设置
可以注意到,当渲染到页面的时候,router-link标签变成了a标签,这是默认下的渲染方式,我们也可以通过其tag属性手动设置渲染后的标签,tag属性的值为渲染后的标签
<div id="app">
<router-link to="/login" tag="span">login</router-link>
<router-link to="/register" tag="p">register</router-link>
<router-view></router-view>
</div>
渲染后为
<div id="app">
<span class="">login</span>
<p class="">register</p>
<!---->
</div>
可以看到两个标签不再是a标签了,而是手动设置的span标签和p标签。
切换的高亮
可以注意到,在点击router-link改变路由时,被点击的元素的class发生了改变,多了router-link-exact-active和router-link-active两个class类选择器,我们可以通过这两个选择器来设置切换时的元素的高亮
<style>
.router-link-active {
color: red;
}
</style>
通过这样设置,在切换路由时,当前路由对应的router-link标签就会多了个color:red的样式。
这个路由高亮的类选择器名比较长,我们通过在路由构建时多添加一个linkActiveClass属性可以自定义一个类选择器名来使用,linkActiveClass属性的值即为高亮时的类选择器样式名。
let myRouter = new VueRouter({
routes: [{
path: '/login',
component: login
}, {
path: '/register',
component: register
}],
linkActiveClass: "myActive"
})
这样设置后,高亮的类选择器名就变成了myActive。
路由的重定向
有时候我们希望在一打开页面时就跳转到另一个hash的页面,可以使用路由的重定向。在构建路由时,在routes属性中通过设置一个path为'/'的对象,给其设置redirect属性,值就为重定向所到的hash。
let myRouter = new VueRouter({
routes: [{
path: '/',
redirect: '/login'
}, {
path: '/login',
component: login
}, {
path: '/register',
component: register
}],
linkActiveClass: "myActive"
})
这里一打开页面就会先跳转到hash为'/login'的页面。
路由的参数
路由传递参数有两种方式
通过query方式传递
通过query方式传递只要在router-link标签的to属性的值后面加上?键值=键名即可。在调用时通过$route.query.键名来调用。
<div id="app">
<router-link to="/login?id=10" tag="span">login</router-link>
<router-link to="/register?id=20" tag="p">register</router-link>
<router-view></router-view>
</div>
<script>
let login = {
template: '<h1>this is login----{{$route.query.id}}</h1>',
created() {
console.log(this.$route) // 在这里可以打印出$route对象来查看里面的内容
}
}
let register = {
template: '<h1>this is register----{{$route.query.id}}</h1>'
}
let myRouter = new VueRouter({
routes: [{
path: '/',
redirect: '/login'
}, {
path: '/login',
component: login
}, {
path: '/register',
component: register
}],
linkActiveClass: "myActive"
})
let vm = new Vue({
el: '#app',
data: {},
methods: {},
router: myRouter
})
</script>
通过params方式传递
与使用query方式传递不同,使用params传递时,要在构建路由实例的时候设置传递的键名,在router-link中设置传递的键值。在调用时是通过$route.params.键名来调用的。
<div id="app">
<!-- 在hash后加/后跟键值 -->
<router-link to="/login/10" tag="span">login</router-link>
<router-link to="/register/20" tag="p">register</router-link>
<router-view></router-view>
</div>
<script>
let login = {
template: '<h1>this is login----{{$route.params.id}}</h1>',
created() {
console.log(this.$route)
}
}
let register = {
template: '<h1>this is register----{{$route.params.id}}</h1>'
}
let myRouter = new VueRouter({
routes: [{
path: '/',
redirect: '/login'
}, {
path: '/login/:id', // 设置键名
component: login
}, {
path: '/register/:id',
component: register
}],
linkActiveClass: "myActive"
})
let vm = new Vue({
el: '#app',
data: {},
methods: {},
router: myRouter
})
</script>
params传递的参数是从path属性中解析出来的,这与query方式传递不同,使用query方式传递时path中并不会出现参数。可以在打印出来的$route中查看属性。
命名路由的使用
除了上面的使用方法,也可以通过名称来标识一个路由以达到方便的效果,使用命名路由也可以简单地传递参数。
<div id="app">
<!-- 注意这里的to使用了v-bind绑定了 -->
<router-link :to="{name:'login',params:{id:10}}">login</router-link>
<router-link :to="{name:'register',params:{id:20}}">register</router-link>
<router-view></router-view>
</div>
<script>
let login = {
template: '<h1>this is login----{{$route.params.id}}</h1>',
created() {
console.log(this.$route)
}
}
let register = {
template: '<h1>this is register----{{$route.params.id}}</h1>'
}
let myRouter = new VueRouter({
routes: [{
path: '/',
redirect: '/login'
}, {
path: '/login/:id',
name: 'login', // 设置路由名称
component: login
}, {
path: '/register/:id',
name: 'register',
component: register
}],
linkActiveClass: "myActive"
})
let vm = new Vue({
el: '#app',
data: {},
methods: {},
router: myRouter
})
</script>
路由的嵌套
实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件。要让router-view中嵌套其他的router-view,需要在VueRouter实例中设置children参数。
<div id="app">
<router-link to="/access">access</router-link>
<router-view></router-view>
</div>
<template id="temp">
<div>
<router-link to="/access/login">登录</router-link>
<router-link to="/access/register">注册</router-link>
<router-view></router-view>
</div>
</template>
<script>
let login = {
template: "<h1>登录</h1>"
}
let register = {
template: "<h1>注册</h1>"
}
let access = {
template: "#temp"
}
let myRoute = new VueRouter({
routes: [{
path: '/access',
component: access,
children: [{ // 设置被嵌套的路由
path: 'login',
// 前面不要加/ 加/表示从根目录开始匹配,加了的话就会变成/login 不加就是/access/login
component: login
}, {
path: 'register',
component: register
}]
}]
})
let vm = new Vue({
el: "#app",
router: myRoute
})
</script>
路由命名视图
如果要在同一个路由下展示多个视图,而不是嵌套展示,可以使用路由的命名视图来实现。在上面代码中,每个path都对应一个component,而如果我们要使用路由的命名视图,我们要用到的是components来传入一个对象,对象中有多个模板,键名为router-view的name属性对应的值,而键值为对应的模板。
<div id="app">
<router-view name="header"></router-view>
<router-view name="left"></router-view>
<router-view name="main"></router-view>
</div>
<script>
let headerTemp = {
template: "<h1>this is header</h1>"
}
let leftTemp = {
template: "<h1>this is left</h1>"
}
let mainTemp = {
template: "<h1>this is main</h1>"
}
let myRouter = new VueRouter({
routes: [{
path: '/',
components: {
header: headerTemp,
left: leftTemp,
main: mainTemp
}
}]
})
let vm = new Vue({
el: "#app",
router: myRouter
})
</script>
使用watch监听路由的改变
路由地址的改变可以通过watch来监听,watch的具体用法可见Vue学习笔记(六)计算属性和监听属性
<div id="app">
<router-link to="/login" tag="span">登录</router-link>
<router-link to="/register">注册</router-link>
<router-view></router-view>
</div>
<script>
let login = {
template: '<h1>登录组件</h1>'
}
let register = {
template: '<h1>注册组件</h1>'
}
let myRouter = new VueRouter({
routes: [{
path: '/',
redirect: '/login' // 默认跳转到/login
}, {
path: '/login',
component: login
}, {
path: '/register',
component: register
}],
linkActiveClass: "myActive" // 高亮属性,默认为router-link-active
})
let vm = new Vue({
el: '#app',
data: {},
methods: {},
router: myRouter,
watch: {
'$route.path': function(newVal, oldVal) {
console.log(`the old is ${oldVal} this new is ${newVal}`)
}
}
})
</script>