【VUE】day07 路由
【VUE】day07 路由
- 1. 路由
- 2. 前端路由的工作方式
- 3. 实现简易的前端路由
- 4. 安装和配置路由
- 4.1 安装`vue-router`包
- 4.2 创建路由模块
- 4.3 导入并挂在路由模块
- 5. 在路由模块中声明路由的对应关系
- 5.1 router-view
1. 路由
在 Vue.js 中,路由(Routing)是通过 Vue Router
实现的。Vue Router
是 Vue.js 官方提供的路由管理器,用于构建单页面应用程序(SPA)。它允许你在不重新加载页面的情况下,动态切换视图和组件,同时保持 URL 的同步。
在 Vue.js 中,路由(Routing)是通过 Vue Router 实现的。Vue Router 是 Vue.js 官方提供的路由管理器,用于构建单页面应用程序(SPA)。它允许你在不重新加载页面的情况下,动态切换视图和组件,同时保持 URL 的同步。
总体来说,可以实现以下的功能
-
通过URL来映射不同的组件,实现页面切换;
-
支持动态路由,使 URL 传递参数;
-
提供嵌套路由,实现多级路由嵌套;
-
支持编程式导航,可以通过 JavaScript 代码进行跳转;
-
提供路由守卫,控制页面访问权限。
核心概念
1. 路由(Route)
路由定义了 URL 和组件之间的映射关系。当用户访问某个 URL 时,Vue Router 会根据路由配置加载相应的组件。
2. 路由表(Routes)
路由表是一个数组,包含多个路由配置。每个路由配置通常包括 path(路径)、component(组件)等属性。
3. 路由器(Router)
路由器是 Vue Router 的核心实例,负责管理路由表和处理路由切换。
4. 路由视图(RouterView)
<router-view>
是一个占位符组件,用于渲染当前路由匹配的组件。
5. 路由链接(RouterLink)
<router-link>
是一个导航组件,用于生成导航链接,点击后会切换到对应的路由。
6. 动态路由
动态路由允许在路径中使用参数(如 /user/:id),这些参数可以在组件中通过 this.$route.params 访问。
7. 嵌套路由
嵌套路由允许在父路由中定义子路由,用于构建复杂的页面结构。
8. 路由守卫(Navigation Guards)
路由守卫是钩子函数,用于在路由切换前后执行某些操作,例如权限验证、数据加载等。
2. 前端路由的工作方式
3. 实现简易的前端路由
但实际应该动态的显示组件
<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(){
window.onhashchange = () =>{
console.log('监听到hash地址的变化',location.hash)
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>
<style lang="less" scoped>
.app-container {
background-color: #efefef;
overflow: hidden;
margin: 10px;
padding: 15px;
> a {
margin-right: 10px;
}
}
</style>
4. 安装和配置路由
vue-router
安装和配置的步骤。
① 安装vue-router
包
② 创建路由模块
③ 导入并挂在路由模块
④ 声明路由链接和占位符
4.1 安装vue-router
包
在vue2的项目中安装vue-router的命令如下:
npm i vue-router@3.5.2 -S
4.2 创建路由模块
在src源代码目录下,新建router/index.js
路由模块,并初始化如下的代码:
// src/router/index.js 就是当前项目的路由模块
import Vue from 'vue'
import VueRouter from 'vue-router'
// 导入需要的组件
import Home from '@/components/Home.vue'
import Movie from '@/components/Movie.vue'
import About from '@/components/About.vue'
import Tab1 from '@/components/tabs/Tab1.vue'
import Tab2 from '@/components/tabs/Tab2.vue'
import Login from '@/components/Login.vue'
import Main from '@/components/Main.vue'
// 把 VueRouter 安装为 Vue 项目的插件
// Vue.use() 函数的作用,就是来安装插件的
Vue.use(VueRouter)
// 创建路由的实例对象
const router = new VueRouter({
// routes 是一个数组,作用:定义 “hash 地址” 与 “组件” 之间的对应关系
routes: [
// 重定向的路由规则
{ path: '/', redirect: '/home' },
// 路由规则
{ path: '/home', component: Home },
// 需求:在 Movie 组件中,希望根据 id 的值,展示对应电影的详情信息
// 可以为路由规则开启 props 传参,从而方便的拿到动态参数的值
{ path: '/movie/:mid', component: Movie, props: true },
{
path: '/about',
component: About,
// redirect: '/about/tab1',
children: [
// 子路由规则
// 默认子路由:如果 children 数组中,某个路由规则的 path 值为空字符串,则这条路由规则,叫做“默认子路由”
{ path: '', component: Tab1 },
{ path: 'tab2', component: Tab2 }
]
},
{ path: '/login', component: Login },
{ path: '/main', component: Main }
]
})
// 为 router 实例对象,声明全局前置导航守卫
// 只要发生了路由的跳转,必然会触发 beforeEach 指定的 function 回调函数
router.beforeEach(function(to, from, next) {
// to 表示将要访问的路由的信息对象
// from 表示将要离开的路由的信息对象
// next() 函数表示放行的意思
// 分析:
// 1. 要拿到用户将要访问的 hash 地址
// 2. 判断 hash 地址是否等于 /main。
// 2.1 如果等于 /main,证明需要登录之后,才能访问成功
// 2.2 如果不等于 /main,则不需要登录,直接放行 next()
// 3. 如果访问的地址是 /main。则需要读取 localStorage 中的 token 值
// 3.1 如果有 token,则放行
// 3.2 如果没有 token,则强制跳转到 /login 登录页
if (to.path === '/main') {
// 要访问后台主页,需要判断是否有 token
const token = localStorage.getItem('token')
if (token) {
next()
} else {
// 没有登录,强制跳转到登录页
next('/login')
}
} else {
next()
}
})
export default router
4.3 导入并挂在路由模块
import Vue from 'vue'
import App from './App2.vue'
// 导入路由模块,目的:拿到路由的实例对象
// 在进行模块化导入的时候,如果给定的是文件夹,则默认导入这个文件夹下,名字叫做 index.js 的文件
import router from '@/router/index.js'
// 导入 bootstrap 样式
import 'bootstrap/dist/css/bootstrap.min.css'
// 全局样式
import '@/assets/global.css'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
// 在 Vue 项目中,要想把路由用起来,必须把路由实例对象,通过下面的方式进行挂载
// router: 路由的实例对象
router
}).$mount('#app')
5. 在路由模块中声明路由的对应关系
5.1 router-view
<router-view>
是 Vue Router 提供的核心组件之一,用于渲染匹配当前路由的组件。它是构建单页面应用(SPA)的关键元素,负责根据路由配置动态加载和显示不同的视图组件。 以下是关于 <router-view>
的详细介绍:
一、<router-view>
的作用与功能
1.动态渲染组件
<router-view>
是一个占位符组件,会根据当前路由路径(URL)自动渲染匹配的组件。例如,当用户访问 /home 时,<router-view>
会渲染 Home 组件。
2.支持嵌套路由
在嵌套路由中,<router-view>
可以嵌套使用,用于渲染子路由对应的组件。例如,父路由 /user 中嵌套子路由 /user/profile,子组件会渲染在父组件的 中。
3.过渡动画
<router-view>
可以与 Vue 的 <transition>
组件结合,为路由切换添加动画效果,提升用户体验。
4,命名视图
支持多视图渲染,通过 name 属性指定不同的视图出口。例如,主视图和侧边栏视图可以分别渲染在不同的 <router-view>
中。
二、基本用法
1.简单示例
在 App.vue 中使用 <router-view>
渲染匹配的组件:
<template>
<div id="app">
<nav>
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
</nav>
<router-view></router-view> <!-- 渲染匹配的组件 -->
</div>
</template>
2.嵌套路由示例
在父组件中嵌套 <router-view>
渲染子路由:
<template>
<div>
<h2>User Page</h2>
<router-link to="/user/profile">Profile</router-link>
<router-link to="/user/posts">Posts</router-link>
<router-view></router-view> <!-- 渲染子路由组件 -->
</div>
</template>
3.过渡动画示例
为路由切换添加淡入淡出效果:
<template>
<div id="app">
<router-view v-slot="{ Component }">
<transition name="fade" mode="out-in">
<component :is="Component" />
</transition>
</router-view>
</div>
</template>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
</style>
其他例子
APP.vue
<template>
<div class="app-container">
<h1>App2 组件</h1>
<!-- 当安装和配置了 vue-router 后,就可以使用 router-link 来替代普通的 a 链接了 -->
<!-- <a href="#/home">首页</a> -->
<router-link to="/home">首页</router-link>
<!-- 注意1:在 hash 地址中, / 后面的参数项,叫做“路径参数” -->
<!-- 在路由“参数对象”中,需要使用 this.$route.params 来访问路径参数 -->
<!-- 注意2:在 hash 地址中,? 后面的参数项,叫做“查询参数” -->
<!-- 在路由“参数对象”中,需要使用 this.$route.query 来访问查询参数 -->
<!-- 注意3:在 this.$route 中,path 只是路径部分;fullPath 是完整的地址 -->
<!-- 例如: -->
<!-- /movie/2?name=zs&age=20 是 fullPath 的值 -->
<!-- /movie/2 是 path 的值 -->
<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>
<router-link to="/about">关于</router-link>
<hr />
<!-- 只要在项目中安装和配置了 vue-router,就可以使用 router-view 这个组件了 -->
<!-- 它的作用很单纯:占位符 -->
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style lang="less" scoped>
.app-container {
background-color: #efefef;
overflow: hidden;
margin: 10px;
padding: 15px;
> a {
margin-right: 10px;
}
}
</style>
// src/router/index.js 就是当前项目的路由模块
import Vue from 'vue'
import VueRouter from 'vue-router'
// 导入需要的组件
import Home from '@/components/Home.vue'
import Movie from '@/components/Movie.vue'
import About from '@/components/About.vue'
import Tab1 from '@/components/tabs/Tab1.vue'
import Tab2 from '@/components/tabs/Tab2.vue'
import Login from '@/components/Login.vue'
import Main from '@/components/Main.vue'
// 把 VueRouter 安装为 Vue 项目的插件
// Vue.use() 函数的作用,就是来安装插件的
Vue.use(VueRouter)
// 创建路由的实例对象
const router = new VueRouter({
// routes 是一个数组,作用:定义 “hash 地址” 与 “组件” 之间的对应关系
routes: [
// 重定向的路由规则
{ path: '/', redirect: '/home' },
// 路由规则,把#去掉
{ path: '/home', component: Home },
// 需求:在 Movie 组件中,希望根据 id 的值,展示对应电影的详情信息
// 可以为路由规则开启 props 传参,从而方便的拿到动态参数的值
{ path: '/movie/:mid', component: Movie, props: true },
{
path: '/about',
component: About,
// redirect: '/about/tab1',
children: [
// 子路由规则
// 默认子路由:如果 children 数组中,某个路由规则的 path 值为空字符串,则这条路由规则,叫做“默认子路由”
{ path: '', component: Tab1 },
{ path: 'tab2', component: Tab2 }
]
},
{ path: '/login', component: Login },
{ path: '/main', component: Main }
]
})
// 为 router 实例对象,声明全局前置导航守卫
// 只要发生了路由的跳转,必然会触发 beforeEach 指定的 function 回调函数
router.beforeEach(function(to, from, next) {
// to 表示将要访问的路由的信息对象
// from 表示将要离开的路由的信息对象
// next() 函数表示放行的意思
// 分析:
// 1. 要拿到用户将要访问的 hash 地址
// 2. 判断 hash 地址是否等于 /main。
// 2.1 如果等于 /main,证明需要登录之后,才能访问成功
// 2.2 如果不等于 /main,则不需要登录,直接放行 next()
// 3. 如果访问的地址是 /main。则需要读取 localStorage 中的 token 值
// 3.1 如果有 token,则放行
// 3.2 如果没有 token,则强制跳转到 /login 登录页
if (to.path === '/main') {
// 要访问后台主页,需要判断是否有 token
const token = localStorage.getItem('token')
if (token) {
next()
} else {
// 没有登录,强制跳转到登录页
next('/login')
}
} else {
next()
}
})
export default router
P7 todo