v-router 路由基础
Posted 小hu同学
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了v-router 路由基础相关的知识,希望对你有一定的参考价值。
导读:由于本篇文章我是在juejin上面发了后,复制过来的,所以会有一些动态图没有动,图片有水印,排版等问题
一、路由的基本概念与原理
1.什么是路由
路由(英文:router)就是对应关系。
2.SPA 与前端路由
SPA 指的是一个 web 网站只有唯一的一个 html 页面,所有组件的展示与切换都在这唯一的一个页面内完成。
此时,不同组件之间的切换需要通过前端路由来实现。 结论:在 SPA 项目中,不同功能之间的切换,要依赖于前端路由来完成!
3.什么是前端路由
概念:Hash 地址与组件之间的对应关系。
4.前端路由的工作方式
① 用户点击
了页面上的路由链接
② 导致了 URL 地址栏
中的Hash
值发生了变化
③ 前端路由监听了到 Hash 地址
的变化
④ 前端路由把当前 Hash 地址
对应的组件渲染到浏览器中
5.实现简易的前端路由
前提准备:
创建一个Vue 项目
创建几个.vue组件,并且导入和注册组件,并且使用
// 后面的才代表的是hash地址 ,如果没有# 则不代表hash地址
<a href="#/home">首页</a>
<a href="#/move">电影</a>
<a href="#/about">关于</a>
<!-- 动态组件 -->
// 动态绑定一个is "comname值",在data中定义默认要展示的是哪个组件
<component :is="comname"></component>
// 导入组件
import Home from '@/components/Home.vue'
import Movie from '@/components/Movie.vue'
import About from '@/components/About.vue'
export default
name: 'App',
data()
return
// 在动态组件要展示的名字
comname:'Home'
,
//created生命周期函数
created()
//只要当前的APP组件被创建,就立即监听widows下面的onhashchange事件 要展示的组件的名字 值必须是字符串 onhashchange 事件
window.onhashchange = ()=>
console.log('监听到了hash地址的变化',location.hash);
//判断hash地址的值 如果等于#/home的值,这comname就改为Home
switch(location.hash)
case'#/home':
this.comname = 'Home'
break
case'#/move':
this.comname = 'Movie'
break
case'#/about':
this.comname = 'About'
break
,
// 注册组件
components:
Home,
Movie,
About
可以看到我这里点击了,a链接,改变了hash的值,页面也跟着变化了
二、vue-router 的基本用法
1.什么是 vue-router
vue-router 是 vue.js 官方给出的路由解决方案。它只能结合 vue 项目进行使用,能够轻松的管理 SPA(单页面)
项目中组件的切换。
vue-router 的官方文档地址:router.vuejs.org/zh/
2.vue-router 安装和配置的步骤
一般我们在创建项目的时候,可以勾选安装 router插件,会默认的帮我们配置好文件夹及文件
- 安装 vue-router 包
- 创建路由模块
- 导入并挂载路由模块
- 声明路由链接和占位符
2.1 安装vue-router 包
npm i vue-router -S
//使用这个命令默认安装最新版本 加上@***,可指定版本号
// -S 是表示将插件安装到 "dependencies"
2.2 创建路由模块
在 src 源代码目录下,新建 router/index.js 路由模块,并初始化如下的代码:
// 当前项目的路由模块
import Vue from 'vue'
import VueRouter from 'vue-router'
// 将 VueRouter安装为use插件里面
// Vue.use 就是来安装插件的
Vue.use(VueRouter)
// 创建一个router实例对象
const router = new VueRouter()
//向外共享路由的实例对象
export default router
2.3 导入并挂载路由模块
在Vue中使用路由,需要在main.js入口文件导入挂载路由
main.js文件
// 导入路由模块 目的 拿到路由的实例对象
// 在模块化导入的时候 默认的会去找index.js
// import router from '@/router/ 这种导入也是可行的
import router from '@/router/index.js'
new Vue(
render: h => h(App),
// 在Vue 项目中 要想吧路由用起来 必须吧路由实例对象 通过下面的方式进行挂载
// router: 路由的实例对象
// 名字和属性名是一样的时候 可简写 router
router: router
).$mount('#app')
2.4 声明路由链接和占位符
App.vue文件
<!-- 当安装和配置了router后 就可以使用 router-link来替代普通的a链接 -->
<!-- <a href="#/homes">首页</a> -->
<router-link to="/homes">首页</router-link>
<router-link to="/Movie">电影</router-link>
<router-link to="/About">关于</router-link>
<!-- 只要在项目中配置了vue-router 就可以使用router-view这个组件了 -->
<!-- 组件渲染到这个里面-->
<!-- 它的作用很单纯 占位符 -->
<router-view></router-view>
3.声明路由匹配规则
在 src/router/index.js 路由模块中,通过 routes 数组声明路由的匹配规则。示例代码如下:
// 导入需要的组件
import Home from '@/components/Home.vue'
import Movie from '@/components/Movie.vue'
import About from '@/components/About.vue'
// 创建一个router实例对象
const router = new VueRouter(
// routes 是一个数组 作用:定义hash 地址与“组件”之间的对应关系
routes: [
// 重定向的路由规则
//当路由访问/为斜杠的hash地址,重定向到/homes组件
path: '/', redirect: '/homes' ,
// 路由规则
//path 代表hash地址 component表示的是组件
path: '/homes', component: Home ,
path: '/Movie', component: Movie ,
path: '/about', component: About
]
)
三、Vue-router的常见用法
1.路由重定向
路由重定向指的是:用户在访问地址 A 的时候,强制用户跳转到地址 C ,从而展示特定的组件页面。通过路由规则的 redirect
属性,指定一个新的路由地址,可以很方便地设置路由的重定向
path: '/', redirect: '/homes' ,
2.嵌套路由
通过路由实现组件的嵌套展示,叫做嵌套路由
2.1 声明子路由链接和子路由占位符
app.vue
<router-link to="/about">关于</router-link>
//父级占位符
<router-view></router-view>
about.vue
<!-- 子集路由链接 -->
<router-link to="/about">tab1</router-link>
<router-link to="/about/tab2">tab2</router-link>
//子级占位符
<router-view></router-view>
注意:需要创建两个组件文件,在引入
2.2 通过 children 属性声明子路由规则
路由模块 router/index.js
//导入组件
import Tab1 from '@/components/tabs/Tab1.vue'
import Tab2 from '@/components/tabs/Tab2.vue'
// 创建一个router实例对象
const router = new VueRouter(
// routes 是一个数组 作用:定义hash 地址与“组件”之间的对应关系
routes: [
path: '/about',
component: About,
//路由重定向
// redirect: '/about/tab1',
children: [
//1、通过children 属性 嵌套声明子级路由规则
// 子路由规则
// 默认子路由 如果children 数组中 某个路由规则的path 值 为空字符串
// 则这条路由规则 叫做“默认子路由”
// path 不要加 /
path: '', component: Tab1 ,
path: 'tab2', component: Tab2
]
,
]
)
3.动态路由匹配
看看下面这个
<!--注意 在hash 地址中 /后面的参数是路径参数 -->
<!-- 在路由参数对象 需要使用this.$route.params 来访问路径参数 -->
<!-- 注意2 在hash地址中 ?后面的参数项 叫做 “查询参数” -->
<!-- 在 路由参数对象中 需要使用this.$route.query来访问查询参数 -->
<!-- 注意3 在this.$route 中 path 只是路径部分 fullPath是完整的hash 地址 -->
<!-- 例如 -->
<!-- /movie/2?name=zs%20age%3D12 是完整的fullPath -->
<!-- /movie/2 是path -->
<router-link to="/movie/1">1</router-link>
<router-link to="/movie/2">2</router-link>
<router-link to="/movie/3">3</router-link>
路由规则
path:'/movie/1',component:Movie
path:'/movie/2',component:Movie
path:'/movie/3',component:Movie
按照上面这种去做的话 代码量会很大,复用性会很低
3.1动态路由的概念
动态路由指的是:把 Hash 地址中可变的部分定义为参数项,从而提高路由规则的复用性。 在 vue-router 中使用英文的冒号(:)来定义路由的参数项。示例代码
// 在movie 组件中 根据id的值 展示对应电影的详细信息
// props:true 为路由开启传参 从而方便拿到动态路由参数的值
//这个id 是自定义名称 和任意定义
path: '/movie/:id', component: Movie, props: true ,
如何获取到id呢?看下图,可以看到我打印了当前的组件实例,可以看到在$route对象下面有一个 params,里面的id就是id值
我们可以渲染到页面上看看
<!-- this.$route 是路由的参数对象 -->
<!-- this.$router 是路由的导航对象 -->
id为props里面接到的id
<h3>Movie 组件-----this.$route.params.id----id</h3>
代码优化:
//直接在props里面接一个id
export default
// 接收props 数据传参
props:[
'id'
],
4.声明式导航&编程式导航
在浏览器中,点击链接实现导航的方式,叫做声明式导航。例如:普通网页中点击
<a>
链接、vue 项目中点击<router-link>
都属于声明式导航
在浏览器中,调用 API 方法实现导航的方式,叫做编程式导航
。
例如: 普通网页中调用 location.href跳转到新页面的方式,属于编程式导航
4.1 vue-router 中的编程式导航 API
vue-router 提供了许多编程式导航的 API,其中最常用的导航 API 分别是:
1.this.$route.push('hash地址')
跳转到指定的hash地址,并增加1条记录
<button @click="tomovie1">push跳转电影1</button>
<script>
export default
name: 'Home',
methods:
tomovie1()
// 通过编程式导航API 跳转到指定的hash地址 并增加一条历史记录
this.$router.push('/movie/1')
,
</script>
2.this.$route.replace('hash地址')
跳转到指定的 hash 地址,并替换掉当前的历史记录
<button @click="tomovie2">replace跳转电影2</button>
<script>
export default
name: 'Home',
methods:
tomovie2()
// 通过编程式导航API 跳转到指定的hash地址 并替换掉当前的历史记录
this.$router.replace('/movie/2')
,
,
</script>
3.this.$route.go(数值n)
实现导航历史前进、后退
<button @click="goto">go后退</button>
<script>
export default
goto()
// go(-1)表示后退一层
// 如果后退的层数超过上限 则原地不动
this.$router.go(-1)
,
</script>
4.2 $router.go的简化用法
在实际开发中,一般只会前进和后退一层页面,因此vue-router提供了如下两个便捷方法:
1、$router.back()
在历史记录中,后退到上一个页面
2、$router.forward()
在历史记录中,前进到下一个页面
<!-- 路由的另一种方式 -->
//在行内使用编程式导航跳转的时候 this必须要省略否则会报错
<button @click="$router.back()" >back后退</button>
<button @click="$router.forward()">forward前进</button>
5 路由导航守卫
导航守卫可以控制路由的访问权限。如下图所示
5.1 全局前置守卫
每次发生路由的导航跳转时,都会触发全局前置守卫。因此,在全局前置守卫中,程序员可以对每个路由进行访问权限的控制:
const router = new VueRouter(...)
//调用路由实例对象的beforEach方法,即可声明“全局前置守卫”
// 每次发生路由导航跳转的时候,都会自都动触发fn 这个“回调函数”
router.beforeEach(fn)
5.2守卫方法的 3 个形参
全局前置守卫的回调函数中接收 3 个形参,格式为:
const router = new VueRouter(...)
//全局前置守卫
router.beforeEach((to,from,next)=>
//to 是将要访问的路由的信息对象
// from 是将要离开的路由的信息对象
// next 是一个函数,调用next()表示放行。允许这次路由导航
)
5.3 next 函数的 3 种调用方式
- 当前用户拥有后台主页的访问权限,直接放行:
next()
- 当前用户没有后台主页的访问权限,强制其跳转登录页面:
next('/login')
- 当前用户没有后台主页的访问权限,不允许跳转到后台主页:
next(false)
5.4 控制后台主页的访问权限
// 为router 实例对象 声明全局前置导航守卫
// 只要发生了路由的
router.beforeEach((to, from, next) =>
console.log(from)
//to 是将要访问的的路由的信息对象
// fromm 是将要离开的路由的信息对象
// next 是一个函数 调用next()表示放行 允许这次对象的运行
// next()
// 1、要拿到用户将要访问的hash地址
// 2、判断hash 地址是否等于 /main
// 如果等于/main 证明需要登录之后 才能访问成功
// 如果不等于/main 这不需要登录 直接放行 next()
//3、如果访问的地址是/main 则需要读取localstorage 里面的值
// 如果有token 这放行
// 如果没有token 则强制跳转到登录页面
if (to.path === '/main')
//要访问后台主页
const token = localStorage.getItem('token')
if (token)
next()
else
// 没有登录强制跳转登录页
next('/login')
else
// 直接放行
next()
)
以上是关于v-router 路由基础的主要内容,如果未能解决你的问题,请参考以下文章