vue-router
vue-router
Jin前端路由
前端路由,指的是 Hash 地址与组件之间的对应关系
工作方式:
- 用户点击了页面的路由链接
- 导致了 URL 地址栏的 Hash 值方式变化
- 前端路由监听到 Hash 地址的变化
- 前端路由把当前 Hash 值地址对应的组件渲染到浏览器页面
简单路由的实现
<!-- a 链接添加对应的 hash 值 -->
<a href="#/home">Home</a>
<a href="#/movie">Movie</a>
<a href="#/about">About</a>
<!-- 动态渲染结点 -->
<!-- 通过 is 属性 指定要展示的组件 -->
<comnponent :is="comName"></comnponent>
<script>
export default{
name:'App',
data(){
return{
comName:'Home'
}
},
// 在 created 生命周期函数中,监听浏览器地址栏中hash 地址的变化
//动态切换要展示的组件的名称
created(){
window.onhashchange=()=>{
switch(location.hash){
case: '#/home':
this.comName = 'Home'
break
case: '#/movie':
this.comName = 'Movie'
break
case: '#/about':
this.comName = 'About'
break
}
}
}
}
</script>
vue-router
vue-router 是 vue.js 官方给出的路由解决方案。它只能结合 vue 项目进行使用,能够轻松的管理 SPA 项目中组件的切换
基本用法
1.安装:在 vue2 的项目中,安装 vue-router@3.5.2
npm i vue-router@3.5.2 -S
2.在项目 src
目录下 新建 router/index.js
路由模块
// 导入 vue 和 vue-router
import Vue from 'vue'
import VueRouter from 'vue-router'
// 调用 Vue.app() 安装 VueRouter
Vue.app(VueRouter)
// 创建路由实例对象
const router = new VueRouter()
// 导出共享
export default router
3.导入挂载,在 src/main.js
入口文件导入挂载路由模块
import Vue from 'vue'
import App from './App.vue'
// 1.导入
import router from './router/index.js'
new Vue({
// 2.挂载
router,
render: (h) => h(App),
}).$mount('#app')
4.声明路由链接和占位符 在 App.vue
里使用 vue-router 提供的 <router-link>
和 router-view
声明路由链接和占位符
<template>
<div>
<h1> App组件 </h1>
<!-- 定义路由链接 -->
<router-link to="/home">首页</router-link>
<router-link to="/movie">电影</router-link>
<router-link to="/about">关于</router-link>
<!-- 定义路由占位符 -->
<router-view></router-view>
</div>
</template>
5.声明路由规则,在路由模块 src/router/index.js
,通过 routers 数组声明匹配规则
// 导入 需要使用路由切换的组件
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '@/component/Home.vue'
import About from '@/component/About.vue'
import Movie from '@/component/Movie.vue'
// 创建路由实例对象
const router = new VueRouter({
// 路由匹配规则
routes
})
const routes = [
// path 表示匹配的 hash 地址
// component 表示要展示的组件
{ path: '/home', component: Home },
{ path: '/about', component: About },
{ path: '/movie', component: Movie },
]
声明式导航
<router-link>
的基本属性
to
一个字符串,或者是一个属性
replace
设置 replace 属性的话,当点击时,会调用 router.replace(),而不是 router.push();
active-class
设置激活a元素后应用的class,默认是router-link-active
exact-active-class
链接精准激活时,应用于渲染的
<a>
的 class,默认是router-link-exact-active;
路由重定向
路由重定向指定的是,用户在访问 A 地址,强制用户跳转到 B 地址
const router = new VueRouter({
routes
})
// 路由匹配规则
const routes = [
// 通过 redirect 属性,设置重定向
// 当用户访问 / 时 跳转到 /home 对应的路由规则
{path:'/',redirect:'/home'},
{ path: '/home', component: Home },
{ path: '/about', component: About },
{ path: '/movie', component: Movie },
]
嵌套路由
通过路由实现组件的嵌套展示,叫做嵌套路由。
在 About.vue 组件中,声明 tab1 和 tab2 的子路由链接以及子路由占位符
<template>
<div class="about-container">
<!-- 要把父路由写上 -->
<router-link to="/about/tab1">tab1</router-link>
<router-link to="/about/tab2">tab2</router-link>
<router-view></router-view>
</div>
</template>
在 src/router/index.js 路由模块中,导入需要的组件,并使用 children 属性声明子路由规则
const routes = [
{
path: '/about',
component: 'About',
children: [
// 注意不要写成 /tab1
{ path: 'tab1', component: Tab1 },
{ path: 'tab2', component: Tab2 },
],
},
]
动态路由匹配
动态路由指的是:把 Hash 地址中可变的部分定义为参数项,从而提高路由规则的复用性。
在 vue-router 中使用英文的冒号(:)来定义路由的参数项。
// 动态参数以 : 进行声明。冒号后面的是动态参数名称
{ path: '/movie/:id', component: Moive },
// 动态路由将下面的规则合成一个提高复用性
{ path: '/movie/1', component: Moive },
{ path: '/movie/2', component: Moive },
{ path: '/movie/3', component: Moive },
参数
动态路由渲染出来的组件中,可以使用 this.$route.params
对象访问到动态匹配的参数值。
<template>
<div class="about-container">
<!-- this.$route 是参数对象 -->
<h3>Movie 组件:接收的参数是{{ this.$route.params }}</h3>
</div>
</template>
为了简化路由参数的获取形式,vue-router 允许在路由规则中开启props 传参
// 定义路由规则时 声明 props:true 选项
{ path: '/movie/:id', component: Moive ,props:true},
<template>
<div class="about-container">
<!-- 使用 props 中接收的参数 -->
<h3>Movie 组件:接收的参数是{{ id}}</h3>
</div>
</template>
<script>
export default{
// 接收路由规则中匹配的参数项 id
props:['id']
}
</script>
编程式导航
声明式导航:
- 通过点击链接实现导航
- 如普通网页点击
a
链接,vue
点击<router-link>
编程式导航:
- 通过调用 API 实现导航
- 普通网页通过
location.href
的方式跳转页面也是编程式导航
vue-router
中实现编程式导航的 API :
this.$router.push('hash地址')
:跳转到指定页面,并增加一条历史记录this.$router.replace('hash地址')
:跳转页面,但不会新增历史记录,而是替换当前的历史记录this.$router.go(数值)
:历史记录前进或后退,相当于点击浏览器前进后退箭头this.$router.forward()
:前进一步this.$router.back()
:后退一步
导航守卫
全局前置守卫
每次发生路由的导航跳转时,都会触发全局前置守卫。因此,在全局前置守卫中,程序员可以对每个路由进行访问权限的控制
// index.js路由模块文件
// 全局前置守卫
router.before({to,from,next}=>{
// to 将要访问的路由
// from 将要离开的路由
// next 是一个函数表示放行
})
next 函数的 3 种调用方式
当前用户拥有后台主页的访问权限,直接放行:next()
当前用户没有后台主页的访问权限,强制其跳转到登录页面:next(‘/login’)
当前用户没有后台主页的访问权限,不允许跳转到后台主页:next(false)
NotFound
对于哪些没有匹配到的路由,我们通常会匹配到固定的某个页面
NotFound的错误页面中,这个时候我们可编写一个动态路由用于匹配所有的页面
{
path: '/:pathMactch(.*)',
component: () => improt('../page/NotFound.vue')
}
通过$route.params.pathMatch
获取到传入的参数
<h2>
Not Found: {{ $route.params.pathMatch }}
</h2>
匹配规则后可加*
{
path: '/:pathMactch(.*)*',
component: () => improt('../page/NotFound.vue')
}
区别:
动态管理路由
动态添加路由
根据用户不同的权限,注册不同的路由,使用一个方法 addRoute
const categoryRoute = {
path: '/category',
component: () => import('../pages/Category.vue')
}
router.addRouter(categoryRoute)
如果添加的路由是一个 children 路由,那么可以传入对应的 name
const homeMomentRoute = {
// 子路由不用加 /
path: 'moment',
component: () => import('../pages/HomeMoment.vue')
}
router.addRouter('home',homeMomentRoute)
删除路由的三种方式
添加相同 name 的路由
router.addRoute({ path: '/about', name: 'about', component: 'About' }) // 删除之前添加的路由,因为 name 是唯一的 router.addRoute({ path: '/other', name: 'about', component: 'About' })
通过 removeRoute 方法,传入路由名称
router.addRoute({ path: '/about', name: 'about', component: 'About' }) router.removeRoute('about')
通过 addRouter 方法返回值回调
const removeRoute =router.addRoute(routeRecord) // 删除路由如果存在 removeRoute()
其他补充方法
router.hasRoute()
:检查路由是否存在。router.getRoutes()
:获取一个包含所有路由记录的数组。