文章目录
- 1. 介绍
- 2. Vue Router 和 Vue 项目集成
- 3. 声明式导航
- 4. 编程式导航
- 5. 重定向和404
- 6. 嵌套路由
- 7. 动态路由匹配
1. 介绍
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于 Vue.js 过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的 CSS class 的链接
- HTML5 历史模式或 hash 模式,在 IE9 中自动降级
- 自定义的滚动条行为
vue-router路由模式:
- hash: 使用 URL hash 值来作路由。支持所有浏览器,包括不支持 HTML5 History的浏览器。
- history: 依赖 HTML5 History API 和服务器配置。
- abstract: 支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式。

2. Vue Router 和 Vue 项目集成
安装:
如果在vue-cli创建项目时没有勾选上vue-router选项,此时就需要手动的来安装它:
npm i -S vue-router@3
注意在 Vue2 中要安装3的版本。
使用步骤:
-
在项目中的
src目录下创建router文件夹,并在router文件夹下创建index.js文件:
-
编写新创建的
index.js文件,并且在入口文件main.js中注入路由这一步可以分为以下几小步:
- 引入相关库文件
- 以插件的方式添加,将VueRouter引入到Vue类中
- 定义渲染的组件
- 实例化路由对象及配置路由表
- 导出路由配置
- 在入口文件注入路由
- 在父组件
App.vue文件中定义路由匹配成功后渲染的挂载点
index.js:
// 1.引入相关库文件 import Vue from 'vue' import VueRouter from 'vue-router'// 3.定义渲染的组件 === 视图组件 容器组件 import Home from '@/views/Home.vue'// 2.以插件的方式添加,将VueRouter引入到Vue类中 Vue.use(VueRouter)// 配置路由表 const routes = [{// 匹配的路由path: '/home',// 匹配成功后要渲染的组件,这些组件会放在 src/views 目录下component: Home} ]// 4.实例化路由对象及配置路由表 const router = new VueRouter({// 路由模式mode: 'history',// 路由规则表routes })// 5.导出 export default routermain.js:
import Vue from 'vue' import App from './App.vue' import router from './router'new Vue({// 要通过 router 配置参数注入路由,从而让整个应用都有路由功能// router:router// 简写router,render: h => h(App) }).$mount('#app')App.vue:
<template><div><!-- 定义路由匹配成功后渲染的挂载点 --><router-view /></div> </template><script> export default {components: {},data() {return {}},methods: {} } </script><style lang="scss" scoped></style>

3. 声明式导航
描述:
它就是先在页面中定义好跳转的路由规则,vueRouter中通过 router-link组件来完成。
语法:
<router-link to="path"></router-link>
# router-link声明式导航,它编译成html的标签为a,在vue-router3版本中可以自定义设置
# router-link 标签中有三个参数+ to: string|{path:string,query:{},params:{}} 表示要跳转到的路由规则,这个参数是必填选项+ tag: 默认编译生成的为a标签,可以自定义+ activeClass 指定激活样式名称,默认名称为:router-link-active
使用:
首先在配置路由表,我们配置 home 页面和 about 页面:
index.js:
// 1.引入相关库文件
import Vue from 'vue'
import VueRouter from 'vue-router'// 3.定义渲染的组件 === 视图组件 容器组件
import Home from '@/views/Home.vue'
import About from '@/views/About.vue'// 2.以插件的方式添加,将VueRouter引入到Vue类中
Vue.use(VueRouter)// 配置路由表
const routes = [{// 匹配的路由path: '/home',// 匹配成功后要渲染的组件,这些组件会放在 src/views 目录下component: Home},{path: '/about',component: About}
]// 4.实例化路由对象及配置路由表
const router = new VueRouter({// 路由模式mode: 'history',// 路由规则表routes
})// 5.导出
export default router
然后在父组件中定义路由跳转规则:
App.vue:
<template><div><ul><li><router-link to="/home" tag="h3" activeClass="active">home</router-link></li><li><router-link to="/about" activeClass="active">about</router-link></li></ul><hr><!-- 定义路由匹配成功后渲染的挂载点 --><router-view /></div>
</template><script>
export default {components: {},data() {return {}},methods: {}
}
</script><style lang="scss" scoped>
.active {color: red;
}
</style>

上面的案例中,我们在 router-link 标签中给入 to 参数的数据为字符串类型,我们还可以给入对象类型:
父组件(App.vue):
<template><div><ul><li><!-- 给入对象传参 --><router-link :to="{ path: '/home', query: { id: 100 } }" activeClass="active">home</router-link></li><li><!-- 给入字符串传参 --><router-link to="/about?id=100" activeClass="active">about</router-link></li></ul><hr><!-- 定义路由匹配成功后渲染的挂载点 --><router-view /></div>
</template><script>
export default {components: {},data() {return {}},methods: {}
}
</script><style lang="scss" scoped>
.active {color: red;
}
</style>

注意:
- 给 to 参数传入对象类型的数据时,必须在 to 前面加冒号
:- 给 to 参数传入对象类型的数据中 query 类型是给地址栏传参用的,当然在给出字符串类型数据时也可以直接写入地址栏数据
4. 编程式导航
描述:
编程式导航就是通过js来实现路由跳转。
语法:
# 能回退 参数:String|Object+ this.$router.push("/login");+ this.$router.push({ path:"/login",query:{username:"jack"} });
# 不能回退 参数:String|Object+ this.$router.replace("/login");+ this.$router.replace({ name:'user' , params: {id:123} });
# n为数字,正数为前进,负数为回退+ this.$router.go( n );//
使用:
在上文声明式导航的基础上,用编程式导航如果要实现在 about 页面中点击按钮,3秒钟之后跳转到 home 页面,我们只需要修改 about 页面。
About.vue:
<template><div><h3>关于我们</h3><button @click="goHome">点击到home</button></div>
</template><script>
export default {methods: {goHome() {// 要求3秒钟之后跳转到 home 页面setTimeout(() => {// 通过this.$router对象中的push/replace方法完成路由切换// push/replace string|object// push/push string|object// this.$router.push('/home')this.$router.push({path: '/home',query: { id: 200 }})}, 3000)}}
}
</script><style lang="scss" scoped></style>

案例——登录成功实现页面跳转:
配置路由(index.js):
// 1.引入相关库文件
import Vue from 'vue'
import VueRouter from 'vue-router'// 3.定义渲染的组件 === 视图组件 容器组件
import Home from '@/views/Home.vue'
import About from '@/views/About.vue'
import Login from '@/views/Login.vue'// 2.以插件的方式添加,将VueRouter引入到Vue类中
Vue.use(VueRouter)// 配置路由表
const routes = [{// 匹配的路由path: '/home',// 匹配成功后要渲染的组件,这些组件会放在 src/views 目录下component: Home},{path: '/login',component: Login}
]// 4.实例化路由对象及配置路由表
const router = new VueRouter({// 路由模式mode: 'history',// 路由规则表routes
})// 5.导出
export default router
父组件(App.vue):
<template><div><router-link to="/login">login</router-link><hr /><!-- 定义路由匹配成功后渲染的挂载点 --><router-view /></div>
</template><script>
export default {components: {},data() {return {};},methods: {},
};
</script><style lang="scss" scoped></style>
登录页面(Login.vue):
<template><div><h3>用户登录</h3><hr /><div><input v-model="username" /></div><div><input v-model="password" /></div><div><button @click="login">进入系统</button></div></div>
</template><script>
export default {data() {return {username: 'admin',password: 'admin'}},methods: {login() {if (this.username === 'admin') {this.$router.replace('/home')} else {alert('登录失败')}}}
}
</script><style lang="scss" scoped></style>

5. 重定向和404
描述:
重定向:用户在访问地址A的时候,强制用户跳转到地址C ,从而展示特定的组件页面。
404:用户访问的页面不存在时,显示的页面
实现方法:
配置路由表(index.js):
// 1.引入相关库文件
import Vue from 'vue'
import VueRouter from 'vue-router'// 3.定义渲染的组件 === 视图组件 容器组件
import Home from '@/views/Home.vue'
import About from '@/views/About.vue'
import Login from '@/views/Login.vue'
import Notfound from '@/views/Notfound.vue'// 2.以插件的方式添加,将VueRouter引入到Vue类中
Vue.use(VueRouter)// 配置路由表
const routes = [{// 匹配的路由path: '/home',// 匹配成功后要渲染的组件,这些组件会放在 src/views 目录下component: Home},{path: '/about',component: About},{path: '/login',component: Login},// 路径为根时,重定向到 home 页面{path: '/',// 重定向redirect: '/home'},// 以上的规则都没有匹配成功,则返回404{path: '*',component: Notfound}
]// 4.实例化路由对象及配置路由表
const router = new VueRouter({// 路由模式mode: 'history',// 路由规则表routes
})// 5.导出
export default router
父组件(App.vue):
<template><div><ul><li><router-link to="/home">home</router-link></li><li><router-link to="/about">about</router-link></li><li><router-link to="/login">login</router-link></li></ul><hr /><!-- 定义路由匹配成功后渲染的挂载点 --><router-view /></div>
</template><script>
export default {components: {},data() {return {};},methods: {},
};
</script><style lang="scss" scoped>
.active {color: red;
}
</style>
404页面(Notfound.vue):
注意:这个页面我们想要实现展示本页面之后 3 秒,路由重定向到 home 页面
<template><div>404</div>
</template><script>
export default {// 在挂载完毕的生命周期函数中执行 3 秒钟后重定向到 home 页面mounted() {// setTimeout(() => {// // 这种写法会让浏览器直接刷新,会结束上一个页面的所有任务,不用考虑销毁,工作中常用// location.href = "/home";// }, 3000);let n = 1;this.timer = setInterval(() => {if (n++ >= 3) {this.$router.push("/home").catch(() => {});}console.log(n);}, 1000);},beforeDestroy() {// 如果计时器存在就清除计时器,防止浏览器卡顿this.timer && clearInterval(this.timer);},
};
</script><style lang="scss" scoped></style>

注意:
注意编程式导航跳转到与当前地址一致的URL时会报错,但是这个报错不影响功能。
Vue Router 版本是3,这是版本 bug,可以修复,也可以不用管。
6. 嵌套路由
描述:
嵌套路由最关键在于理解子级路由的概念:
比如我们有一个/users的路由,那么/users下面还可以添加子级路由,如:
/users/index、/users/add等等,这样的路由情形称之为嵌套路由。
语法:
routes: [{ path: "/user", component: User,//通过 children 属性为 /user 添加子路由规则children:[{ path: "/user/index", component: Index },{ path: "/user/add", component: Add },]}
]# 需要在 User组件中定义一个router-view 用于嵌套路由的渲染显示
<router-view></router-view>
案例:
-
需求:
登陆成功后会在 localStorage 中写入 token 值,并且跳转到后台管理页(admin),将后台汇总页和用户页作为子路由嵌套在后台管理页里。如果登录失败,后台管理页检测不到 localStorage 中的 token 值,会重新返回到登录页面,即登录失败,不会显示后台管理页。
-
实现
配置路由:
// 1.引入相关库文件 import Vue from 'vue' import VueRouter from 'vue-router'// 3.定义渲染的组件 === 视图组件 容器组件 import Login from '@/views/Login.vue' import Admin from '@/views/Admin' import Dashboard from '@/views/Dashboard' import User from '@/views/User'// 2.以插件的方式添加,将VueRouter引入到Vue类中 Vue.use(VueRouter)// 配置路由表 const routes = [{path: '/login',component: Login},// 嵌套路由{path: '/admin',component: Admin,// 重定向redirect: '/admin/dashboard',// 嵌套路由children: [{// 这里访问的是这个路径:/admin/dashboradpath: 'dashboard',component: Dashboard},{path: 'user',component: User}]} ]// 4.实例化路由对象及配置路由表 const router = new VueRouter({// 路由模式mode: 'history',// 路由规则表routes })// 5.导出 export default router父组件(App.vue):
<template><div><!-- 定义路由匹配成功后渲染的挂载点 --><router-view /></div> </template><script> export default {components: {},data() {return {};},methods: {}, }; </script><style lang="scss" scoped></style>登录页(Login.vue):
<template><div><h3>用户登录</h3><hr /><div><input v-model="username" /></div><div><input v-model="password" /></div><div><button @click="login">进入系统</button></div></div> </template><script> export default {data() {return {username: 'admin',password: 'admin'}},methods: {login() {if (this.username === 'admin') {localStorage.setItem('token','fewfewlfewlkfewlkfelfew')// this.$router.replace('/admin/dashboard')this.$router.replace('/admin')// this.$router.replace('/home')} else {alert('登录失败')}}} } </script><style lang="scss" scoped></style>后台管理页(admin.vue):
<template><div><h3>后台管理</h3><hr /><menus /><!-- 嵌套路由,一定要在父路由中添加对应的 挂载点 --><router-view /></div> </template><script> import menu from './ui/menu.vue' export default {components: {menus: menu},// 在嵌套路由的父级中书写业务代码,可以实现登录跳转// 如果登录不成功就无法获取token值,此时重定向到登录页面created() {if (!localStorage.getItem('token')) {this.$router.replace('/login')}} } </script><style lang="scss" scoped></style>
7. 动态路由匹配
描述:
所谓动态路由就是路由规则中有部分规则是动态变化的,不是固定的值,需要去匹配取出数据(即路由参数)。
比如我们有这样一个场景,在页面中有新闻 1 、新闻 2 、新闻 3 三个选项,点击不同的选项会显示不同的新闻详情页,那么我们要如何实现这个功能呢?
我们可以通过?在地址栏传入 id 值,通过参数控制跳转。但是这种方式不够安全,有可能会暴露后台数据。而且当地址栏中出现?时,浏览器会判定当前页面为动态网站,动态网站在 SEO 搜索引擎中权重比静态网站要低,不利于 SEO 优化。
所以,当我们需要一个唯一标识来控制显示哪个页面时,就需要用到动态路由匹配。
动态路由匹配安全性更高,且会被浏览器判定为静态页,在搜索引擎中排名较高。
语法:
// 传递参数id
var router = new VueRouter({// routes是路由规则数组 routes: [{ path: '/user/:id', component: User },]
})// 组件中获取id值
const User = {template: '<div>User ID is {{$route.params.id}}</div>'
}
使用:
路由配置(index.js):
// 1.引入相关库文件
import Vue from 'vue'
import VueRouter from 'vue-router'// 3.定义渲染的组件 === 视图组件 容器组件
import News from '@/views/News'
import Detail from '@/views/Detail'// 2.以插件的方式添加,将VueRouter引入到Vue类中
Vue.use(VueRouter)// 配置路由表
const routes = [{path: '/news',component: News},// 动态路由参数,一定要先定义,后使用{// :名称 定义动态路由参数的方式,可以定义N个 /:a/:b/:c// path: '/detail/:nid',// 可选路由参数,即没有参数也可以访问到详情页面path: '/detail/:nid?',component: Detail}
]// 4.实例化路由对象及配置路由表
const router = new VueRouter({// 路由模式mode: 'history',// 路由规则表routes
})// 5.导出
export default router
新闻页面(index.vue):
<template><div><li><!-- 这里也可以传入 query 数据 --><router-link to="/detail/1?name=abc">新闻1</router-link></li><li><router-link to="/detail/2">新闻2</router-link></li><li><router-link to="/detail/3">新闻3</router-link></li></div>
</template><script>
export default {}
</script><style lang="scss" scoped></style>
新闻详情页(index.vue):
<template><div><h3>详情页面 --- {{ $route.params.nid || 0 }} == {{ nid }}</h3></div>
</template><script>
export default {computed: {nid() {// 返回动态路由参数return this.$route.params.nid || 0}},mounted() {// 获取动态路由传过来的 query 数据// 注意:这里获取的数据是个对象,对象的属性值是字符串,如果要参与数值运算需要先转化为数值console.log(this.$route.query)},
}
</script><style lang="scss" scoped></style>

注意:
如果不使用动态路由参数,而使用 query 的方式(即在地址栏中传入
?)向地址栏中传入数据:优点:不需要提前定义,只要传入字符串即可,操作方便。
缺点:不利于 SEO 优化;地址栏不优雅;暴露了敏感字段,安全性低。
如果使用动态路由参数,使用 params 的方式匹配动态路由:
优点:地址栏很优雅,没有问号;搜索引擎权重高;隐藏了字段名,安全性更高。
缺点:必须要先定义后使用,如果是对于很多项不确定的参数使用这种方式的话,定义起来会变得很麻烦。














