您好,欢迎来到99网。
搜索
您的当前位置:首页vue路由个人详细总结,这些路由知识你都了解吗?

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

来源:99网

what is 路由 and SPA

路由?

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

SPA?

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

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

后端路由?

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

前端路由?

路由的hash模式和history模式

前端路由的工作方式

手动模拟前端路由实现

<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.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参数

⑦路由的params参数



⑧路由命名 用于简化跳转

⑨路由的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()  前进

路由守卫

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

路由文章参考

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 99spj.com 版权所有 湘ICP备2022005869号-5

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务