admin管理员组文章数量:1633774
路由
路由(router)也就是对应关系。
-
SPA
SPA 指一个 web 网站只有唯一的一个 HTML 页面,所有组件的展示与切换都在这一个页面内完成,也就是单页面应用。
不同组件之间的切换需要通过前端路由来实现。
-
前端路由
概念:Hash 地址与组件之间的对应关系。
-
工作方式:
① 用户点击页面上的路由链接
② URL 地址栏中的 Hash 值发生了变化
③ 前端路由监听Hash 地址的变化
④ 前端路由把当前 Hash 地址对应的组件渲染都浏览器中
-
实现简易的前端路由:
-
<!--APP.vue中-->
<template>
<div class="app-container">
<h1>App 根组件</h1>
<a href="#/home">首页</a>
<a href="#/movie">电影</a>
<a href="#/about">关于</a>
<hr />
<component :is="comName"></component>
</div>
</template>
<script>
// 创建并导入组件
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() {
// App 组件一被创建,立即监听 window 对象的 onhashchange 事件
//默认像是Home组件,当Hash地址发生变化,页面显示的组件也发生变化
window.onhashchange = () => {
switch (location.hash) {
case '#/home':
this.comName = 'Home'
break
case '#/movie':
this.comName = 'Movie'
break
case '#/about':
this.comName = 'About'
break
}
}
},
// 注册组件
components: {
Home,
Movie,
About
}
}
</script>
(简易的前端路由只是用来展示一下工作原理,实际开发中我们不需要这种方式,接下来介绍vue-router)
-
vue-router
vue-router 是 vue.js 官方给出的路由解决方案,能够轻松管理 SPA 项目中组件的切换(只能结合 vue 项目进行使用)。
-
vue-router的安装和配置步骤
(1)安装 vue-router 包
npm i vue-router@3.5.2 -S (@后面接版本)
(2)创建路由模块
在src目录下,新建router/index.js 路由模块,并初始化:
import Vue from 'vue' import VueRouter from 'vue-router' // 把 VueRouter 安装为 Vue 项目的插件 // Vue.use() 函数的作用,就是来安装插件的 Vue.use(VueRouter) // 创建路由的实例对象 const router = new VueRouter({}) //向外共享路由实例对象 export default router
(3)导入并挂载路由模块
在src/main.js入口文件中,导入并挂载路由模块:
import Vue from 'vue' import App from './App.vue' //导入模块 import router from '@/router' new Vue({ render: h => h(App), // 路由挂载 // router: 路由的实例对象 router }).$mount('#app')
(4) 声明路由链接和占位符
在 src/App.vue 组件中,使用 vue-router 提供的 和 声明路由链接和占位符:
<template> <div class="app-container"> <h1>App 组件</h1> <!-- 当安装和配置了 vue-router 后,就可以使用 router-link 来替代普通的 a 链接了 --> <!-- <a href="#/home">首页</a> --> <router-link to="/home">首页</router-link> <router-link to="/movie">电影</router-link> <router-link to="/about">关于</router-link> <hr /> <!-- 在项目中安装和配置了 vue-router,就能使用 router-view 这个组件了 --> <!-- 定义路由占位符 --> <router-view></router-view> </div> </template>
(5)声明路由的匹配规则(一一对应)
在 src/router/index.js 路由模块中,通过 routes 数组声明路由的匹配规则(注意这里是routes而不是router)
// 导入需要的组件 import Home from '@/components/Home.vue' import Movie from '@/components/Movie.vue' import About from '@/components/About.vue' Vue.use(VueRouter) // 创建路由的实例对象 const router = new VueRouter({ // routes 是一个数组,作用:定义 “hash 地址” 与 “组件” 之间的对应关系 routes: [ { path: '/home', component: Home }, { path: '/movie', component: Movie }, { path: '/about', component: About }, ] })
-
路由重定向
用户在访问地址 A 的时候,强制用户跳转到地址 C ,从而展示特定的组件页面。通过路由规则的 redirect 属性,指定一个新的路由地址来设置路由的重定向:
//在 src/router/index.js 路由模块中的 routes 数组添加:
//当用户访问 / 时, 通过redirect 属性跳转到/home对应的路由
{path: '/', redirect: '/home'}
-
嵌套路由
通过路由实现组件的嵌套展示,叫做嵌套路由。
-
衔接笔记上面的代码举例,在About.vue中创建子路由链接和子路由占位符:
<template> <div class="about-container"> <h3>About 组件</h3> <!-- 子级路由链接 --> <router-link to="/about/tab1">tab1</router-link> <router-link to="/about/tab2">tab2</router-link> <hr /> <!-- 子级路由占位符 --> <router-view></router-view> </div> </template>
-
通过 children 属性声明子路由规则
//在 src/router/index.js 路由模块中,导入需要的组件,并使用 children 属性声明子路由规则: //在components中新建tabs文件夹,创建Tab1.vue和Tab2.vue(Tab1和Tab2设置一些文字和背景颜色即可,这里省略) //导入组件: import Tab1 from '@/components/tabs/Tab1.vue' import Tab2 from '@/components/tabs/Tab2.vue' const router = new VueRouter({ routes: [ { path: '/about', component: About, children: [ // 子路由规则 // 默认子路由:如果 children 数组中,某个路由规则的 path 值为空字符串,则这条路由规则,叫做“默认子路由” { path: 'tab1', component: Tab1 }, { path: 'tab2', component: Tab2 } ] } ] })
效果如图:
点击tab1:
点击tab2:
-
如果希望点击“关于”之后,默认打开tab1组件,可以使用redirect: ‘/about/tab1’ ;也可以使用默认子路由的方式:
//修改上面代码 { path: '/about', component: About, // redirect: '/about/tab1', children: [ //如果 children 数组中,某个路由规则的 path 值为空字符串,则这条路由规则叫做“默认子路由” //同时在About.vue中修改子路由tab1链接路径:<router-link to="/about/">tab1</router-link> { path: ' ', component: Tab1 }, { path: 'tab2', component: Tab2 } ] },
-
-
动态路由
- 动态路由指的是:把 Hash 地址中可变的部分定义为参数项,从而提高路由规则的复用性。 在 vue-router 中使用英文的冒号(:)来定义路由的参数项。例如:
//在src/router/index.js中修改匹配规则: //冒号后面也可以用'id' { path: '/movie/:mid', component: Movie, props: true }, //修改APP.vue中代码: <router-link to="/movie/1">洛基</router-link> <router-link to="/movie/2?name=zs&age=20">雷神</router-link> <router-link to="/movie/3">复联</router-link> //这样点击后都能跳转到Movie组件,代替了写多个匹配规则,提高了复用性
-
在动态路由渲染出来的组件中,使用this.$ route.params 对象访问到动态匹配的参数值。在上面的例子中,使用this.$route.params.mid就能查看。
-
为了简化路由参数的获取形式,vue-router 允许在路由规则中开启 props 传参:
//src/router/index.js中: { path: '/movie/:mid', component: Movie, props: true }, //Movie.vue中: export default { name: 'Movie', // 接收 props 数据,即可获得mid props: ['mid'], }
补充:
- 在 hash 地址中, / 后面的参数项,叫做“路径参数”
- this.$route.params 用来访问路径参数
- 在 hash 地址中,? 后面的参数项,叫做“查询参数”
- 在路由“参数对象”中,需要使用 this.$route.query 来访问查询参数
- 在 this.$route 中,path 只是路径部分;fullPath 是完整的地址
- 例如:/movie/2?name=zs&age=20 是 fullPath 的值 而/movie/2 是 path 的值
-
声明式导航 & 编程式导航
-
通过点击链接实现导航的方式,叫做声明式导航。普通网页中点击 a 链接、vue 项目中点击 都属于声明式导航
-
调用 API 方法实现导航的方式,叫做编程式导航。例:普通网页中调用 location.href 跳转到新页面的方式,属于编程式导航
-
vue-router 中的编程式导航 API:
最常用的导航 API 分别是:
(1) this.$router.push(‘hash 地址’)
跳转到指定 hash 地址,并增加一条历史记录(网页能够往前和后退历史)
(2)this.$router.replace(‘hash 地址’)
跳转到指定的 hash 地址,并替换掉当前的历史记录(网页不能回到前一个页面)
(3) this.$router.go(数值 n,正数前进,负数后退)
实现导航历史前进、后退;
在实际开发中,一般只会前进和后退一层页面,两个便捷方法: $router.back(),在历史记录中,后退到上一个页面; $router.forward(),在历史记录中,前进到下一个页面
-
-
全局前置守卫
- 每次发生路由的导航跳转时,都会触发全局前置守卫。因此,在全局前置守卫中,可以对每个路由进行访问权限的控制:
//在src/router/index.js中:
//to表示将要访问的路由信息对象
//from表示将要离开的路由信息对象
//next是函数,表示放行,允许这次路由导航
router.beforeEach((to,from,next) => {})
- next 函数的 3 种调用方式:
(图片来自网上)
当前用户拥有后台主页的访问权限,直接放行:next()
当前用户没有后台主页的访问权限,强制其跳转到登录页面:next(’/login’)
当前用户没有后台主页的访问权限,不允许跳转到后台主页:next(false)
- 控制后台主页的访问权限
//在src/router/index.js下
//声明全局前置导航守卫
// 只要发生了路由的跳转,必然会触发 beforeEach 指定的 function 回调函数
router.beforeEach(function(to, from, next) {
// 首先判断是否跳转到/main后台,如果不是直接放行;
//如果是 /main,则需要登录才能访问,
//读取 localStorage 中的 token 值,如果有 token,则放行;
//如果没有 token,则跳转到 /login 登录页
if (to.path === '/main') {
//判断是否有 token
const token = localStorage.getItem('token')
if (token) {
next()
} else {
next('/login')
}
} else {
next()
}
})
本文标签: 路由
版权声明:本文标题:Vue2学习(7) 路由 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1729175947a1188718.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论