vue路由个人详细总结,这些路由知识你都了解吗?

what is 路由 and SPA

路由?

在这里插入图片描述
①一个路由就是一组映射关系(key-value)
②key为路径,value可能是function或者component

不管生活中使用的路由器还是开发中遇到的router,路由都是一种对应关系,即key与value的对应关系。

在这里插入图片描述

SPA?

SPA指的是一个web网站只有一个唯一的Html页面,所有的组件的展示与切换都在这一个页面来完成。此时,不同组件之间的切换需要通过前端路由来实现。
①单页Web应用(SPA)
②整个应用只有一个完整的页面。vue项目中所有的组件的信息都会展示到public/index.html中
③点击页面中的导航链接不会刷新页面,只会做页面的局部更新。
④数据需要通过ajax请求获取

结论:在SPA项目中,不同功能的实现,需要路由来完成。

后端路由?

①理解:value是function,用于处理客户端提交的请求。
②工作过程:服务器接收到一个请求时,根据请求路径找到匹配的函数来处理请求,返回响应数据。

前端路由?

理解:value是component,用于展示页面内容。
工作过程:当浏览器的路径改变时,对应的组件就会显示。

①hash地址与组件之间的对应关系。
②Hash地址就是锚链接 ,在一个页面中进行组件之间的跳转;而超链接,会跳转到新的页面 锚链接与超链接的区别
③在浏览器console中获取完整的地址,location.href 在一个页面中跳转到不同的路由,#后面的叫做hash地址 location.hash

路由的hash模式和history模式

在这里插入图片描述
在这里插入图片描述
hash模式和history模式区别
hash模式和history模式 面试区别

前端路由的工作方式

用户点击路由链接,浏览器url上的hash地址发生了变化,前端路由监听hash地址的变化,然后前端路由将hash地址对应的组件渲染到浏览器中
在这里插入图片描述

手动模拟前端路由实现

这里我们手动取监听hash地址的变化,后面我们会引入Vue-Router这个第三方库,来帮我们实现路由的的监听和切换

<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 事件
    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>

vue中使用路由的注意点

①路由组件通常粗放在pages文件夹,一般组件存放在components文件夹,路由组件也就是配置了路由的
②通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载。
③每个组件都有自己的 r o u t e 属性,里面存储着自己的路由信息。④整个应用只有一个 r o u t e r ,可以通过组件的 route属性,里面存储着自己的路由信息。 ④整个应用只有一个router,可以通过组件的 route属性,里面存储着自己的路由信息。整个应用只有一个router,可以通过组件的router属性获取到。
r o u t e 是参数对象,可以用来传参; route是参数对象,可以用来传参; route是参数对象,可以用来传参;router是导航对象,组件之间的切换。

引入vue-router的步骤

vue-router官网地址
vue-router是vue.js官方给出的路由解决方案你。他只能结合vue项目来使用,能够轻松管理SPA项目中组件的切换。

①安装

在这里插入图片描述

②创建路由模块

在这里插入图片描述

③导入并挂载路由模块

在这里插入图片描述

④声明路由链接和占位符

在这里插入图片描述

⑤通过routes数组声明路由的匹配规则

在这里插入图片描述

vue-router的常见用法

①路由重定向

在这里插入图片描述

②嵌套路由

在这里插入图片描述

声明子路由链接和子路由占位符

在这里插入图片描述
标签中可以添加active-class=“active”属性来实现高亮效果
active-class 选择样式时根据路由中的路径(to=“/home”)去匹配,然后显示

通过children属性来声明子路由规则

在这里插入图片描述

嵌套路由注意点

在这里插入图片描述
路由匹配的过程中,路由会自动遍历子路由,会给他加上 / ,所以这里不要重复加了

③动态路由匹配

在这里插入图片描述

什么是动态路由?

在这里插入图片描述

$route.params对象

在这里插入图片描述

使用props接收路由参数

在这里插入图片描述

④声明式导航&编程式导航

在这里插入图片描述

vue-router中的编程式导航API

在这里插入图片描述

$router.push()

在这里插入图片描述

$router.replace()

在这里插入图片描述

$router.go()

在这里插入图片描述

$router.back() && $router.forward()

在这里插入图片描述

⑤导航守卫

在这里插入图片描述

全局前置守卫

在这里插入图片描述

守卫方法的三个形参

在这里插入图片描述

next()函数的三种调用方式

在这里插入图片描述

控制后台主页的访问权限

在这里插入图片描述

给路由添加鉴权属性

在这里插入图片描述

全局后置路由守卫

后置路由守卫实现的效果,在路由跳转之后修改相应的title

在这里插入图片描述

// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import About from '../pages/About'
import Home from '../pages/Home'
import News from '../pages/News'
import Message from '../pages/Message'
import Detail from '../pages/Detail'

//创建并暴露一个路由器
const router =  new VueRouter({
	routes:[
		{
			name:'guanyu',
			path:'/about',
			component:About,
			meta:{title:'关于'}
		},
		{
			name:'zhuye',
			path:'/home',
			component:Home,
			meta:{title:'主页'},
			children:[
				{
					name:'xinwen',
					path:'news',
					component:News,
					meta:{isAuth:true,title:'新闻'}
				},
				{
					name:'xiaoxi',
					path:'message',
					component:Message,
					meta:{isAuth:true,title:'消息'},
					children:[
						{
							name:'xiangqing',
							path:'detail',
							component:Detail,
							meta:{isAuth:true,title:'详情'},

							//props的第一种写法,值为对象,该对象中的所有key-value都会以props的形式传给Detail组件。
							// props:{a:1,b:'hello'}

							//props的第二种写法,值为布尔值,若布尔值为真,就会把该路由组件收到的所有params参数,以props的形式传给Detail组件。
							// props:true

							//props的第三种写法,值为函数
							props($route){
								return {
									id:$route.query.id,
									title:$route.query.title,
									a:1,
									b:'hello'
								}
							}

						}
					]
				}
			]
		}
	]
})

//全局前置路由守卫————初始化的时候被调用、每次路由切换之前被调用
router.beforeEach((to,from,next)=>{
	console.log('前置路由守卫',to,from)
	if(to.meta.isAuth){ //判断是否需要鉴权
		if(localStorage.getItem('school')==='atguigu'){
			next()
		}else{
			alert('学校名不对,无权限查看!')
		}
	}else{
		next()
	}
})

//全局后置路由守卫————初始化的时候被调用、每次路由切换之后被调用
router.afterEach((to,from)=>{
	console.log('后置路由守卫',to,from)
	document.title = to.meta.title || '硅谷系统'
})

export default router
独享路由守卫

在这里插入图片描述

组件内路由守卫

在这里插入图片描述

⑥路由的query参数

在这里插入图片描述
注意1:在 hash 地址中, / 后面的参数项,叫做“路径参数” 比如/1 /2 这些动态参数 是路径参数
在路由“参数对象”中,需要使用 this.$route.params 来访问路径参数

注意2:在 hash 地址中,? 后面的参数项,叫做“查询参数”
在路由“参数对象”中,需要使用 this.$route.query 来访问查询参数

注意3:在 this.$route 中,path 只是路径部分;fullPath 是完整的地址

⑦路由的params参数

在这里插入图片描述
在这里插入图片描述
路由的params和query传参区别

⑧路由命名 用于简化跳转

在这里插入图片描述

⑨路由的props配置

在这里插入图片描述
组件来接收props传递的数据

<template>
	<div>
		<h1>{{msg}}</h1>
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
		<h2>学生年龄:{{myAge+1}}</h2>
		<button @click="updateAge">尝试修改收到的年龄</button>
	</div>
</template>

<script>
	export default {
		name:'Student',
		data() {
			console.log(this)
			return {
				msg:'我是一个尚硅谷的学生',
				myAge:this.age
			}
		},
		methods: {
			updateAge(){
				this.myAge++
			}
		},
		//简单声明接收
		// props:['name','age','sex'] 

		//接收的同时对数据进行类型限制
		/* props:{
			name:String,
			age:Number,
			sex:String
		} */

		//接收的同时对数据:进行类型限制+默认值的指定+必要性的限制
		props:{
			name:{
				type:String, //name的类型是字符串
				required:true, //name是必要的
			},
			age:{
				type:Number,
				default:99 //默认值
			},
			sex:{
				type:String,
				required:true
			}
		}
	}
</script>

⑩router-link的replace属性

在这里插入图片描述

11、 缓存路由组件

在这里插入图片描述
include中包含的是要缓存的组件的名称,如果keep-alive中不加include,那么所有在router-view中展示的组件都会被缓存

<!-- 缓存多个路由组件 -->
		<!-- <keep-alive :include="['News','Message']"> -->	
		<!-- 缓存一个路由组件 -->
		<keep-alive include="News">
			<router-view></router-view>
		</keep-alive>
<template>
	<ul>
		<li>news001 <input type="text"></li>
		<li>news002 <input type="text"></li>
		<li>news003 <input type="text"></li>
	</ul>
</template>

<script>
	export default {
		name:'News',//这是组件名称
		beforeDestroy() {
			console.log('News组件即将被销毁了')
		},
	}
</script>

12、路由所独有的两个钩子

在这里插入图片描述

vue-router的具体使用

①整体架子

本地项目 vue2/day7/router-demo1
在这里插入图片描述
在这里插入图片描述

②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

③main.js

import Vue from 'vue'
import App from './App2.vue'
// 导入路由模块,目的:拿到路由的实例对象
// 在进行模块化导入的时候,如果给定的是文件夹,则默认导入这个文件夹下,名字叫做 index.js 的文件
import router from '@/router'

// 导入 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')

④App2.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 地址中, / 后面的参数项,叫做“路径参数”  比如/1 /2 这些动态参数 是路径参数 -->
    <!-- 在路由“参数对象”中,需要使用 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>

⑤About.vue

<template>
  <div class="about-container">
    <h3>About 组件</h3>

    <!-- 子级路由链接 -->
    <router-link to="/about">tab1</router-link>
    <router-link to="/about/tab2">tab2</router-link>

    <hr />

    <!-- 子级路由占位符 -->
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'About'
}
</script>

<style lang="less" scoped>
.about-container {
  min-height: 200px;
  background-color: skyblue;
  padding: 15px;
  > a {
    margin-right: 10px;
  }
}
</style>

⑥Home.vue

<template>
  <div class="home-container">
    <h3>Home 组件</h3>

    <hr />

    <button @click="gotoLk">通过 push 跳转到“洛基”页面</button>
    <button @click="gotoLk2">通过 replace 跳转到“洛基”页面</button>
    <router-link to="/main">访问后台主页</router-link>
  </div>
</template>

<script>
export default {
  name: 'Home',
  methods: {
    gotoLk() {
      // 通过编程式导航 API,导航跳转到指定的页面
      this.$router.push('/movie/1')
    },
    gotoLk2() {
      this.$router.replace('/movie/1')
    }
  }
}
</script>

<style lang="less" scoped>
.home-container {
  min-height: 200px;
  background-color: pink;
  padding: 15px;
}
</style>

⑦Login.vue

<template>
  <div>
    <h3>Login 登录页面</h3>
  </div>
</template>

<script>
export default {}
</script>

<style></style>

⑧Main.vue

<template>
  <div>
    <h3>Main 后台主页,未登录不允许访问!!!</h3>
  </div>
</template>

<script>
export default {}
</script>

<style></style>

⑨Movie.vue

<template>
  <div class="movie-container">
    <!-- this.$route 是路由的“参数对象” -->
    <!-- this.$router 是路由的“导航对象” -->
    <h3>Movie 组件 --- {{ $route.params.mid }} --- {{ mid }}</h3>
    <button @click="showThis">打印 this</button>
    <button @click="goback">后退</button>
    <!-- 在行内使用编程式导航跳转的时候,this 必须要省略,否则会报错! -->
    <button @click="$router.back()">back 后退</button>
    <button @click="$router.forward()">forward 前进</button>
  </div>
</template>

<script>
export default {
  name: 'Movie',
  // 接收 props 数据
  props: ['mid'],
  methods: {
    showThis() {
      console.log(this)
    },
    goback() {
      // go(-1) 表示后退一层
      // 如果后退的层数超过上限,则原地不动
      this.$router.go(-1)
    }
  }
}
</script>

<style lang="less" scoped>
.movie-container {
  min-height: 200px;
  background-color: lightsalmon;
  padding: 15px;
}
</style>

⑩关键知识点

this.$route 是路由的“参数对象”

 this.$route.params用来获取路径参数  / 后面的是路径参数
 this.$route.query用来获取查询参数  ?后面的是查询参数
 fullPath包括路径参数和查询参数
 path只包含路径,无查询参数

在这里插入图片描述

this.$router 是路由的“导航对象”

this.$router.push()  跳转到某一个组件,有历史记录
this.$router.replace()   跳转,替换掉当前的历史记录
this.$router.go()   跳转多少页
this.$router.back()  后退
this.$router.forward()  前进

路由守卫

只记录了常用的 前置路由守卫,其他参考官网

路由守卫其他种类

路由文章参考

vue2 vue3路由不同的创建

vue路由

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值