- Published on
Vue-router,在静态切换的世界中翱翔
- Authors
- Name
- Hansuku
什么是 router
首先知道,Vue 是适合在 SPA(单页应用)开发中使用的,router 能够做到类似 html5 和 jQuery 中的 pjax(局部刷新,无刷新切换路由)的效果,也是 Web 应用的路由管理系统。
router 快速上手
- 安装 Vue-router
npm install vue-router --save-dev
如果配置过 vue-cli 则不需要主动去安装 Vue-router,在安装 Vue-cli 的时候是可以选择一起安装的。 - Vue 配置 安装会在源码目录下安装 router 文件夹和 index.js 文件 默认配置:
import Vue from 'vue' //引入Vue
import Router from 'vue-router' //引入Vue-router
import HelloWorld from '@/components/HelloWorld' //引入Components里的HelloWorld.vue
Vue.use(Router) //全局使用路由
export default new Router({
routes: [
//路由配置数组
{
path: '/', //路径
name: 'HelloWorld', //路由名称
component: HelloWorld, //模板组件
},
],
})
尝试在 components 下新建一个 vue 模板,然后在 index.js 里写入
{
path:'/Hi',
name:'Hi',
component:Hi
}
在 router 里根据上面的格式写入路由数组就可以添加路由,并且还要在头部 import 引入一下import Hi from '@/components/Hi'
然后看到 src 源码目录下的 App.vue,这里是 VueRouter 的全局页面
<template>
<div id="app">
<img src="./assets/logo.png">
<router-view/>
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
我们打开本地阅览,尝试在 host 后面加上 Hi,发现可以跳到刚刚配置的 Hi.vue 页面,但是只有局部,上面 Vue 默认的图片还是存在,这就是 router 的奇妙之处,在刚刚打开的 App.vue 里,可以看到一句<router-view/>
这里就是 Vue 作为引导,把其他路由页面加入到这个页面的组件。设想我们需要做一个 SaaS,就可以在这个页面写导航栏,而剩下的部分则依靠<router-view/>
引入切换
- 说到导航栏,其实 Vue 给我们提供了一个新标签(也可以说是新组件),来制作导航栏 我们在 App.vue 全局页面里写入
<template>
<div id="app">
<img src="./assets/logo.png">
<div>
<router-link to="/">首页</router-link>
<router-link to="/Hi">Hi</router-link>
</div>
<router-view/>
</div>
</template>
然后在浏览器中看到,已经有了两个导航按钮 我们注意到地址栏,然后点击 Hi,发现已经能够无需刷新网页,就可以切换页面和路由,这就是 router 的强大之处
子路由
在实际构建网站中,我们会遇到二级栏目的情况,例如我们鼠标 hover 到关于上,会显示出关于我们和联系我们,这两个栏目都隶属于关于,所以就有了子路由的配置 假设我们把导航变成
<div>
<router-link to="/">首页</router-link>|
<router-link to="/Hi">Hi页面</router-link>|
<router-link to="/Hi1">Hi1页面</router-link>|
<router-link to="/Hi2">Hi2页面</router-link>
</div>
Hi1 和 Hi2 是 Hi 的子页面,然后我们希望这两个子页在 H 页面的底部,这种情况的话,我们需要在之前 components 下的 Hi.vue 写入
<template>
<div>
<h2>{{ msg }}</h2>
<router-view/>
</div>
</template>
新建 Hi1.vue 和 Hi2.vue,改改 msg 做区别,然后在 index.js 写入路由配置
{
path:'/Hi',
name:'Hi',
component:Hi,
children:[
{path:'/Hi1',component:Hi1},
{path:'/Hi2',component:Hi2},
]
}
这样就可以让 Hi1 和 Hi2 继承 Hi
参数传递
在 OA 和 SaaS 开发中,我们经常遇到需要在路由中传递参数的情况,而使用 router 时<router-link to="/">首页</router-link>|
并不能传递参数,那就可以使用之前 index.js 在配置路由时一直没用过的 name
{
path: '/',
name: 'youNeed',
component: HelloWorld
}
假设我们需要在跳转到 HelloWorld 的时候接收到 youNeed 首先在 App.vue 全局页面写一个假装是面包屑的标签 <p>{{ $route.name }}</p>
保存好,然后就在 HelloWorld 页面看到我们定义的 youNeed 然后尝试给有子路由增加 name 参数
{
path:'/Hi',
name:'Hi',
component:Hi,
children:[
{path:'/hi1',name:'here hi1',component:Hi1},
{path:'/hi2',name:'here hi2',component:Hi2},
]
}
也能在浏览器中看到效果了。 但是这种方法并不常用,实际开发中,我们的传参是动态的,那就需要改造一下<router-link to="/Hi1">Hi1页面</router-link>
改造成
<router-link :to="{ name:'here hi1',params:{username:'Hansuku',id:'666' }}">Hi1页面</router-link>
这里的 name 要和 index.js 路由配置中的 name 一致,params 接数组对象,然后在 Hi1 模板写入
<h2>{{ msg }}-{{ $route.params.username }}-{{ $route.params.id }}</h2>
这样就能接收到参数了。我们可以通过动态传参的方法去更改 username 和 id 的 value.
单页面多路由操作
什么是单页面多路由操作,假设一个页面里我们有几个
<router-view/>
<router-view name="left"/>
<router-view name="right"/>
然后我们新建一个 hello1.vue 和 hello2.vue 写好相应的区分,在 index.js 中写入路由配置:
{
path: '/',
name: 'youNeed',
components: {
defaule:HelloWorld,
left:Hello1,
right:Hello2
}
}
deafult 是默认配置,left 和 right 则对应了刚才的<router-view name="left"/>
,刷新就能看到效果了
通过 url 传递参数
上面提到的传递参数的方法,都是不会在 url 中体现的,而有的时候我们会喜欢用 url 来辨识文章或者一些操作,那就需要用 url 传参 新建一个 params.vue 的模板
<template>
<h2>{{msg}}</h2>
</template>
<script>
export default{
data(){
return{
msg:'parmas pages'
}
}
}
</script>
index.js 引入import Params from '@/components/params
添加路由
{
path:'/params/:newsID/:newsTit',
component:Params
}
这里的格式是路径+冒号+属性 然后在 App.vue 导航栏加个<router-link to="/params/200/hansuku you">params</router-link>
params 后面跟着的其实就是 url 参数了,点击试试就能看到路由中已经带了参数。接收方式有很多种,vue 的方法是
<p>newsID:{{ $route.params.newsID }}</p>
配置路由时还能做一些验证,比如 newsID 必须是数字
path:'/params/:newsID(\\d+)/:newsTit',
直接括号里面写正则即可
router 重定向
重定向即两个不同的路由打开的页面是一样的,类似返回首页的效果。 添加路由规则配置
{
path:'/goIndex',
redirect:'/'
}
在 App.vue 里添加一个导航<router-link to="/goIndex">返回首页</router-link>
即可 重定向传参 类似上面的路由传参,添加路由配置
{
path:'/goParams/:newsID(\\d+)/:newsTit',
redirect:'/params/:newsID(\\d+)/:newsTit'
}
添加导航: <router-link to="/goParams/199/thisIsParams2">params2</router-link>
一样可以传递参数并且跳转。主要,如果是重定向的 path 里写入了参数传递,而跳转的时候没有带参数,跳转后在页面内会什么都不显示
alias 别名
alias 别名的方式也可以实现类似重定向的效果,区别在于上面的 redirect 跳转后 url 内的地址就是重定向的地址,不会有区别,而 alias 别名是一个新的 url 地址,但是页面是一样的
{
path:'/Hi1',
name:'Hi1',
component:Hi1,
alias:'/Hansuku'
}
这个时候,导航<router-link to="/Hi1">Hi1</router-link>
和<router-link to="/Hansuku">Hansuku</router-link>
跳转的页面内容是一样的,但是地址是http://localhost:8080/#/Hi1
和http://localhost:8080/#/Hansuku
路由过渡动画
在路由切换的时候,由于用户体验不到刷新感,我们需要增添一些过渡动画来提升用户体验 在 router-view 标签即页面会切换内容的地方包裹一层 transition
<transition name="fade" mode="out-in">
<router-view/>
</transition>
name 代表渐入渐出式,mode 是出入循序
out-in 代表先出后入
in-out 代表先入后出
然后增加 css
.fade-enter {
opacity:0;
}
.fade-leave{
opacity:1;
}
.fade-enter-active{
transition:opacity .5s;
}
.fade-leave-active{
opacity:0;
transition:opacity .5s;
}
这样就有了一个比较基础的切换效果
路由模式
export default new Router({
mode:'history',
routes: [
{
path: '/', //路径
name: 'HelloWorld', //路由名称
component: HelloWorld //模板组件
}
]
})
这里的 mode 代表路由模式,加上 mode:'history'
后,本身我们路由里面会带一个#号,现在就消失了,mode 还有一个模式 mode:'hash'
这个模式会带上#号,选择上个人喜好就好。
404 处理
VUE 如果不配置,发生了 404 的情况下用户会比较懵逼的,不知道网页出了什么错,就是不显示 添加配置
{
path:'*',
component:Error
}
*就是对所有没有的路由展示 Error 页面 引入import Error from '@/components/Error'
然后自由配置一个 404 模板即可
路由中的钩子函数
钩子函数能够监听两个状态,一个是进路由之前,一个是离开路由之前,配置钩子函数可以在 index 中写,也可以在模板中写 index.js 中的钩子函数
{
path:'/params/:newsID(\\d+)/:newsTit',
component:Params,
beforeEnter:(to,from,next)=>{
console.log(to),
console.log(from),
next(true)
}
}
next(true)是相当于一个开关的角色,如果换成了 false 就不会进行跳转,如果不写也会导致不跳转 模板中的钩子函数
export default{
data(){
return{
msg:'parmas pages'
}
},
beforeRouteEnter:(to,from,next)=>{
console.log("进入");
next()
},
beforeRouteLeave:(to,from,next)=>{
console.log("离开");
next()
}
}
编程式导航
假设需要一个后退和前进的按钮(类似 chrome 左上角的按钮) html
<button @click="goBack">后退</button>
<button @click="goDo">前进</button>
script
export default {
name: 'app',
methods:{
goBack(){
this.$router.go(-1);
},
goDo(){
this.$router.go(1);
}
}
}
需要注意的是,在没有历史记录的情况下$router.go 是不起作用的
- 编程式跳转
<button @click="goHome">返回首页</button>
goHome(){
this.$router.push('/');
}
方法跟$router.go 大同小异,可以 push 任意页面