目录
一,路由理解
1)理解: 一个路由(route)定制化开发就是一组映射关系(key-value),定制化开发多个路由需要路由器(router)进行管理
2)前端路由:key是路径,value是组件
3)作用:定制化开发设定访问路径,定制化开发并将路径和组件映射起来(定制化开发就是用于局部刷新页面,定制化开发不需要请求服务器来切换页面)
二,基本配置
前期准备: 安装vue-router 全局配置 ,命令: npm i vue-router (定制化开发默认安装的是4定制化开发版本适配的是vue3,定制化开发如果使用的是vue2的话,必须选定3版本 npm i vue-router@3。
第一步: 在main.js定制化开发文件中引入并使用插件
- // 第一步: 引入router 插件
- import VueRouter from 'vue-router'
- // 使用插件
- Vue.use(VueRouter)
第二步: 在src定制化开发文件夹下创建一个router定制化开发文件夹然后在文件夹下创建index.js
index.js定制化开发中写路由的核心代码
- // 定制化开发该文件是专门用于创建定制化开发整个应用的路由器
-
- // 定制化开发第一步引入插件(定制化开发本质是一个构造函数)
- import VueRouter from 'vue-router'
-
- // 定制化开发引入一下用到的组件
- import About from '../components/About'
-
- // 定制化开发第二步创建router定制化开发实例对象并暴露
- export default new VueRouter({
- routes: [
- {
- // path是路径
- path: "/about",
- //定制化开发跳转的组件
- component: About
- },
- ]
- })
- // 然后去main.js中引入router实例
第三步: 回到main.js中引入创建的 router 并在vue实例对象中使用
- // 引入Vue
- import Vue from 'vue'
- // 引入App
- import App from './App'
- // 第一步: 引入router 插件
- import VueRouter from 'vue-router'
- // 使用插件
- Vue.use(VueRouter)
- // 第二步: 创建router文件夹 引入实例
- import router from './router'
-
- // 关闭生产提示
- Vue.config.productionTip = false
-
-
- // 创建vm
- new Vue({
- // 指定容器
- el: '#app',
- // 解析App模板
- render: h => h(App),
- // 使用路由
- router
- })
路由的基本就配置完成了
三,路由的使用
实例演示,先把静态页面准备好。
第一点:在路由中的改变
由路由管理的地方 a标签转换成 router-link 标签 href="相对路径" 变成 to="路由路径"
要显示组件的地方需要用到 router-view占位,当点击时显示About组件中的内容时就会替换掉router-view
通常由路由管理的组件单独放在pages文件夹下,不需要在App组件中引入和注册
- <template>
- <div>
- <div class="row">
- <Banner></Banner>
- </div>
- <div class="row">
- <div class="col-xs-2 col-xs-offset-2">
- <div class="list-group">
- <!-- a标签在路由器中被router-link取代 -->
- <!-- 使用路由提供的标签 点击跳转到/about路径 显示哪个组件在路由中配置好-->
- <!-- active-class 点击时激活类名 -->
- <router-link class="list-group-item" active-class="active" to="/about"
- >About</router-link>
- <router-link class="list-group-item" active-class="active" to="/home"
- >Home</router-link>
- </div>
- </div>
- <div class="col-xs-6">
- <div class="panel">
- <div class="panel-body">
- <!-- 这里存放由路由分配 这里放显示的组件类似于slot-->
- <!-- 显示的组件会替换掉router-view -->
- <router-view></router-view>
- </div>
- </div>
- </div>
- </div>
- </div>
- </template>
-
- <script>
- // 自己引入的组件 由路由管理的组件成为路由组件,通常放在pages文件夹下面
- // 和普通的组件分开 而且不需要引入和注册
- import Banner from "./components/Banner";
- export default {
- name: "App",
- // 组测组件
- components: { Banner },
- };
- </script>
-
- <style>
- </style>
路由中的配置
- // 该文件是专门用于创建整个应用的路由器
-
- // 第一步引入插件(本质是一个构造函数)
- import VueRouter from 'vue-router'
-
- // 引入要用到的组件
- import About from '../pages/About'
- import Home from '../pages/Home'
-
- // 第二步创建router实例对象并暴露
- export default new VueRouter({
- routes: [
- {
-
- // 当路径跳转到/about时显示About组件
- path: "/about",
- component: About
- },
- {
- path: "/home",
- component: Home
- }
- ]
- })
- // 然后去main.js中引入router实例
第二点,多级路由
多级路由用到了children属性 routes中的属性成为一级路由,一级路由中children属性中的沉稳给二级路由以此类推,出一级路由中路径要写斜杠/ 二级路由和多级路由中的路径不写斜杠/
跳转多级路由时,to="路由路径" 要写全!从一级路由开始写!(如: to="/home/news")
可以给路由配置name属性,传递参数的时候会用到,添加name属性后跳转就不用写全路径,可以直接写路由的name (:to="{name:'msg'}")
- routes:[
- {
- path:'/about',
- component:About,
- },
- {
- path:'/home',
- component:Home,
- children:[ //通过children配置子级路由
- {
- name:'news'
- path:'news', //此处一定不要写:/news
- component:News
- },
- {
- name:'message'
- path:'message',//此处一定不要写:/message
- component:Message,
- children: [
- {
- name:'msg'
- path: 'msgdata',
- component: Msgdata,
- }
- ]
- }
- ]
第三点,路由的传参
有两种传参方式,第一种query传参 第二种params传参
query传参
有两种写法 一个是字符串写法直接写在路径中拼接 ?+参数 ,
第二种时对象写法 ,把路径单独写,数据单独写
数据传递根据的是路由路径
- <!-- 跳转并携带query参数,to的字符串写法 -->
- <router-link :to="/home/message/detail?id=666&title=你好">跳转</router-link>
-
- <!-- 跳转并携带query参数,to的对象写法 -->
- <!-- name:'detail' 可以写路由的name 也可以直接写路径 -->
- <router-link
- :to="{
- path:'/home/message/detail',
- query:{
- id:666,
- title:'你好'
- }
- }"
- >跳转</router-link>
组件接收数据
用到$route.query
- <template>
- <div>
- <h3>信息编号:{{ $route.query.id }}</h3>
- <h3>信息标题:{{ $route.query.title }}</h3>
- </div>
- </template>
-
- <script>
- export default {
- name: "Msgdata",
- };
- </script>
-
- <style>
- </style>
当有多个需要传递的参数时,总在模板中写 $route.query, 肯定是不好的,这时候就需要路由中接收并包装一下
还可以在路由设置中进行获取然后再传递到组件 可以用到props,写在组件的路由中
- routes:[
- {
- path:'/about',
- component:About,
- },
- {
- path:'/home',
- component:Home,
- children:[ //通过children配置子级路由
- {
- name:'news'
- path:'news', //此处一定不要写:/news
- component:News
- },
- {
- name:'message'
- path:'message',//此处一定不要写:/message
- component:Message,
- children: [
- {
- path: 'msgdata',
- component: Msgdata,
- //在这里接收一下传来的参数,然后包装一下再传给组件
- props($route){
- return {id:$route.query.id,title:$route.query.title}
- }
- }
- ]
- }
- ]
组件接收一下
- <template>
- <div>
- <h3>信息编号:{{ id }}</h3>
- <h3>信息标题:{{ title }}</h3>
- </div>
- </template>
-
- <script>
- export default {
- name: "Msgdata",
- props: ["id", "title"],
- };
- </script>
-
- <style>
- </style>
params传参
params传递参数也有两种方式
第一种直接路径传递参数
在路径中直接加 引号内的东西都会当成字符处理,所以给to加上冒号让他解析成表达式,但是表达式没有以斜杠开头的,所以加上` 模板引号 又变成了字符串,然后用${}配合模板字符串。
- <router-link :to="`/home/news/shownews/${n.id}/${n.name}`">
- {{ n.name }}
- </router-link>
第二种方式写成对象形式
第二种方式必须写name不可以用path作为路径
- <router-link
- :to="{
- // 用params传递参数时用到他的对象写法中不可使用 path:'路径'
- name: 'shownews',
- params: {
- id: n.id,
- name: n.name,
- },
- }"
- >
- {{ n.name }}
- </router-link>
!!!
传递但是,params传递需要路由路径中配置占位符不然不知道哪个是路径哪个是数据
- name: 'shownews',
- // params 写法先在路径中占位 路径后面跟上占位符
- path: 'shownews/:id/:name',
- component: ShowNews,
组件使用时和query相似
- <ul>
- <!-- query里面写数据 -->
- <li>编号{{ $route.params.id }}</li>
- <li>姓名{{ $route.params.name }}</li>
- </ul>
这里也是如果有很多数据需要用时,可以借助路由包装一下,只需要props的值为true
- name: 'shownews',
- // params 写法先在路径中占位
- path: 'shownews/:id/:name',
- component: ShowNews,
- // props的第二种写法 props为布尔值,会接收所有params参数 以props的形式传递给Detail组件
- props: true
- <template>
- <ul>
- <!-- query里面写数据 -->
- <li>编号{{ id }}</li>
- <li>姓名{{ name }}</li>
- </ul>
- </template>
-
- <script>
- export default {
- name: "ShowNews",
- props: ["id", "title"],
- };
- </script>
replace属性
```<router-link>```的replace属性 不留下操作记录
1. 作用:控制路由跳转时操作浏览器历史记录的模式
2. 浏览器的历史记录有两种写入方式:分别为```push```和```replace```,```push```是追加历史记录,```replace```是替换当前记录。路由跳转时候默认为```push```
3. 如何开启```replace```模式:```<router-link replace .......>News</router-link>```
四,编程式路由导航
1.作用:不借助```<router-link> ```实现路由跳转,让路由跳转更加灵活,不仅a标签可以跳转,
按钮也可以跳转
2. 借助两个API push和replace
- //$router的两个API
- //push跳转 有操作记录
- this.$router.push({
- name:'xiangqing',
- params:{
- id:xxx,
- title:xxx
- }
- })
- //replace 跳转没有操作记录 把之前的replace跳转记录销毁
- this.$router.replace({
- name:'xiangqing',
- params:{
- id:xxx,
- title:xxx
- }
- })
三个操作函数
this.$router.forward() //前进
this.$router.back() //后退
this.$router.go() //可前进也可后退
五,缓存组件和两个生命周期钩子
1,缓存路由组件
1. 作用:让不展示的路由组件保持挂载,不被销毁。
2. 具体编码:
<keep-alive include="要缓存的组件名" >
<router-view></router-view>
</keep-alive>
如果想要缓存多个组件 :include="['News','message']" (冒号不要忘了,双引号里面要用单引号)
-
-
- <keep-alive include="News">
-
- <router-view></router-view>
-
- </keep-alive>
2,两个新的生命周期钩子
1. 作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态。
2. 具体名字:
1)activated路由组件被激活时触发。
2)deactivated路由组件失活时触发。
六,路由守卫
1. 路由守卫的作用 : 对路由进行权限管理,必须符合条件才能访问。
2.路由守卫有三种: 全局守卫、独享守卫、组件内守卫
第一种,全局守卫
在所有的路由发生改变前都执行 使用路由守卫就不能直接暴露路由实例,需要接收一下
然后调用里面的beforeEach((to,from,next)=>{})
有三个参数to:去哪个路径,from:从哪个路径里来,next:是个函数调用的时候next()放行
- // 配置在实例对象外 初始化时调用,每次发生路由变化前调用
- router.beforeEach((to,from,next)=>{
- console.log('beforeEach',to,from)
- if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制
- if(localStorage.getItem('school') === 'atguigu'){ //权限控制的具体规则
- next() //放行
- }else{
- alert('暂无权限查看')
- // next({name:'guanyu'})
- }
- }else{
- next() //放行
- }
- })
-
- //全局后置守卫:初始化时执行、每次路由切换后执行
- router.afterEach((to,from)=>{
- console.log('afterEach',to,from)
- if(to.meta.title){
- document.title = to.meta.title //修改网页的title
- }else{
- document.title = 'vue_test'
- }
- })
第二种,独享守卫
放在需要进行权限设置的路由里面,参数语法和全局一样 当访问这个路径前才执行beforeEnter()
- beforeEnter(to,from,next){
- console.log('beforeEnter',to,from)
- if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制
- if(localStorage.getItem('school') === 'atguigu'){
- next()
- }else{
- alert('暂无权限查看')
- // next({name:'guanyu'})
- }
- }else{
- next()
- }
- }
第三种,组件守卫
放在组件里和methods,components同级别 ,
必须是通过路由规则进入该组件才可以调用
beforeRouteEnter(),beforeRouteLeave()
-
-
- //进入守卫:通过路由规则,进入该组件时被调用
- beforeRouteEnter (to, from, next) {
- },
- //离开守卫:通过路由规则,离开该组件时被调用
- beforeRouteLeave (to, from, next) {
- }