Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:
vue-router路由模式:
安装:
如果在vue-cli创建项目时没有勾选上vue-router选项,此时就需要手动的来安装它:
npm i -S vue-router@3
注意在 Vue2 中要安装3的版本。
使用步骤:
在项目中的src
目录下创建router
文件夹,并在router
文件夹下创建index.js
文件:
编写新创建的index.js
文件,并且在入口文件main.js
中注入路由
这一步可以分为以下几小步:
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 router
main.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>
描述:
它就是先在页面中定义好跳转的路由规则,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">homerouter-link>
li>
<li>
<router-link to="/about" activeClass="active">aboutrouter-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">homerouter-link>
li>
<li>
<router-link to="/about?id=100" activeClass="active">aboutrouter-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 类型是给地址栏传参用的,当然在给出字符串类型数据时也可以直接写入地址栏数据
描述:
编程式导航就是通过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">点击到homebutton>
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">loginrouter-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>
描述:
重定向:用户在访问地址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">homerouter-link>
li>
<li>
<router-link to="/about">aboutrouter-link>
li>
<li>
<router-link to="/login">loginrouter-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>404div>
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,可以修复,也可以不用管。
描述:
嵌套路由最关键在于理解子级路由的概念:
比如我们有一个/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/dashborad
path: '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>
描述:
所谓动态路由就是路由规则中有部分规则是动态变化的,不是固定的值,需要去匹配取出数据(即路由参数)。
比如我们有这样一个场景,在页面中有新闻 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>
<router-link to="/detail/1?name=abc">新闻1router-link>
li>
<li>
<router-link to="/detail/2">新闻2router-link>
li>
<li>
<router-link to="/detail/3">新闻3router-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 的方式匹配动态路由:
优点:地址栏很优雅,没有问号;搜索引擎权重高;隐藏了字段名,安全性更高。
缺点:必须要先定义后使用,如果是对于很多项不确定的参数使用这种方式的话,定义起来会变得很麻烦。