Vue-Router

发布时间 2023-12-05 23:54:51作者: 一笔带过

Rouer组件

可以构造单页引用
多页应用:mpa 每一个页面都是一个html文件 方便seo优化
单页应用:spa 
		知乎网站 掘进 百度移动端
单页用于取决情况:
	1.用户群体比较多
原理:相当于一个a标签,导航栏上切换不同的视图

大部分做的vue 使用都是后台管理程序

在使用router是 vue就会提供一个变量 $route的路由对象这个对象是挂载到每一个实例中每一个组件都可以用的,这个对象中有各种获取对应的url的属性

作用

vue + vue-roure 主要做单页面应用
single page application 简称 spa
为什么要是用单页应用
1.传统的开发
url 改变后,立马发送请求 ,响应整个页面,有可能资源过多,传统开发会让前端的页面出现白屏
用户体验不好
2.spa 单页应用:锚点值的改变,不会立刻发请求,而是在某个合适的时机,发送ajax请求,局部改变页面后的数据,页面 不会立即跳转


原理:相当于根据url 的不同切换不同的页面,但是只在当前的页面进行渲染

怎么使用vue-rouer
需要在创建vue项目中 选中当前的 vue-rouer 组件 
vue create 项目名称  启动后就选中rouer组件就可以
api 网站:https://router.vuejs.org/zh/api/#%E5%8F%82%E6%95%B0-2

创建

1.在创建vue项目是直接使用vue-rueter

2.如果没有那么直接进行安装 
// 1.安装 需要根据当前nodejs的版本与脚手架版本进行安装
npm install vue-router@4
yarn add vue-router@4

// 2.需要在项目中的router/index.js文件中进行设置路由对象
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)

// 路由列表
const routes = [

]

// 创建路由对象
const router = new VueRouter({
    mode: 'history',
    base: process.env.BASE_URL,
    routes
  })

export default router

//3.在main.js文件进行导入挂载全局
import Vue from 'vue'
import App from './App.vue'
import router  from './router' // 导入路由对象

Vue.config.productionTip = false

new Vue({
    router, // 挂载全局
    render: h => h(App),
}).$mount('#app')

// 4.在APP.vue文件中
<router-view/> // 当前全部路由的文件出口(子文件要从这个出口出去)

// 补充在rouer组件中挂载两个对象
this.$route 和 this.$router
this.$route 是专门用来获取路由中参数的
this.$router 是专门来实现编程式导航的

this.$route是路由参数对象,所有路由中的参数,params,query都属于他
this.$router 是一个路由(导航对象),用它方便的使用js 代码,实现路由的前进,后退,跳转到新的url地址

// 两个对象的由来
在源码中:install.js文件中

抛出了两个属性,可以通过this 进行使用
Object.defineProperty(Vue.prototype, '$router', {
    get () { return this._routerRoot._router }
})

Object.defineProperty(Vue.prototype, '$route', {
    get () { return this._routerRoot._route }
})
创建了两个公共 组件
Vue.component('RouterView', View)
Vue.component('RouterLink', Link)
这个是在使用vue-rouer时创建js文件

import Vue from 'vue' // 导入vue对象
import VueRouter from 'vue-router'  //导入 组件


Vue.use(VueRouter)  // 解释看下面

const routes = [
  {
    path: '/',
    name: 'home',  //  给路由命名
    component: () => import('../views/HomeView.vue') // 当启动项目时,就会加载这个页面,不推荐使用
  },
  {
    path: '/about',
    name: 'about',
    component: () => import('../views/AboutView.vue')  // 异步加载路由,当载路由
  }
]

const router = new VueRouter({
  mode: 'history',  // 当前的模式
  base: process.env.BASE_URL,  //
  routes  // 当前的路由列表
})

export default router  // 抛出路由对象



官方对 Vue.use() 方法的说明:通过全局方法 Vue.use() 使用插件,Vue.use 会自动阻止多次注册相同插件,它需要在你调用 new Vue() 启动应用之前完成,Vue.use() 方法至少传入一个参数,该参数类型必须是 Object 或 Function,如果是 Object 那么这个 Object 需要定义一个 install 方法,如果是 Function 那么这个函数就被当做 install 方法。在 Vue.use() 执行时 install 会默认执行,当 install 执行时第一个参数就是 Vue,其他参数是 Vue.use() 执行时传入的其他参数。就是说使用它之后调用的是该组件的install 方法


在vue项目中配置文件中都做了什么:就是挂载了这个 vue-rouer这个组件,挂载到全局中
import Vue from 'vue'
import App from './App.vue'
import router from './router' // 导入router

Vue.config.productionTip = false

new Vue({
  router,  // 挂载router
  render: h => h(App)
}).$mount('#app')

vue-rouer官方网站:https://router.vuejs.org/zh/

Rouer开始

router-link与router-view

// 当使用vue-rouet的时候,就会在两个全局的组件

// 1.会被渲染成为a标签 to会被渲染成href属性
<router-link to=''></router-link>

//2.全部路由组件的出口,全部的路由组件都会从这个方法中出来路由匹配的内容都会从这个地方渲染出来
如果是嵌套的父路由组件必须有router-view作为子组件路由的出口
<router-view/>  代表路由的出口

$route与$routes

在使用vue-rouet组件时,会提供两个属性:1.$router(相当于VueRouter)  2.$route(路由信息配置信息)
//获取路由的参数 存在的query查询参数  和params搜索 参数  都存在这里面(url,参数,别名,等等)
    console.log(this.$route) 
// 获取的路由对象全部的信息都存在这里面相当于VueRouter对象
    console.log(this.$router)

命名路由

1.在对路由进行设置是,设置name属性
  {
    path: '/',
    name: 'home',  //  给路由命名
    component: () => import('../views/HomeView.vue') //异步 加载路由,点击才会 加载
  },
      
 2.使用命名的路由
 <router-link :to="{name:'home'}">主页</router-link> 
 :to="{name:'路由的命名'}"  使用v-bind进行绑定to  将命名的部分填写

3.直接使用地址to属性不需要进行bind绑定(这时to是静态的,如果路径修改,那么当前访问就会出错)
<router-link to="/">主页</router-link> 
  

路由起别名

{
    path: '/home', // 路由url
    name: 'Home', //路由的名称
    component: Home //组件
    alias:"/aaa"  // 给路由起别名 这个别名可以映射到这个对应的路由中 用的不多,
},
    
使用alias属性是可以映射路由
正常访问 127.0.0.1:8080/home
使用alias属性 127.0.0.1:8080/aaa //也可以访问到Home组件

命名视图使用(1个路由显示多个组件)

可以将多个组件同时渲染到一个模板上
在一个路由中显示两个组件的内容怎么设置
在一个页面显示多个组件
使用场景:
网站上 侧边栏,顶部栏,内容,底部栏,需要同时显示在一个页面上

1.路由设置
// 当访问/路由时,可以直接同时在一个页面显示多个组件
{
    path: "/",
    name:'Home',
    // component 指定单个组件    
    // 需要设置components属性 指定多个组件 
    components:{
       // default 默认显示组件 
       default:()=>import('@/components/HeaderView'),
       // 视图命名,相当于给给一个组件命名   
       mian:()=>import('@/components/MianView'), //设置命名main
       sidebar:()=>import('@/components/SidebarView')
       }
},
    

2.在组件中的设置
router-view 标签是可以设置样式的 默认在页面会被渲染为div标签
router-view 的name属性可以指定设置视图命名的组件可以进行显示

<router-view></router-view>  显示默认default 组件
<router-view name="main"></router-view> 显示命名mian的组件
<router-view name="sidebar"></router-view> 显示命名为sidebar组件



这样的情况下就会将3个组件同时渲染到浏览器页面上,更好的区分各个组件的作用和功能,

命名路由参数

params和query

路由参数的范式:
1.在路由下给一个参数(查询参数,动态的参数)称为params
xxx.html/user/1  
2.查询参数在路由中给一个查询 参数(搜索参数)  称为 query
xxx.html/user?id=1

动态参数params

类似于: http://127.0.0.01:8080/index/1

1.使用参数params动态的使用
路由定义:
{
	path: '/about/:user', //动态的路由参数,以:开头 可以传递多个
	name: 'about', // 路由命名
	component: () => import('../views/AboutView.vue')// 异步加载  
}

2.在组件中进行传递动态参数
params:{user:1,'age':...,'sex':...} 可以传递多个值
<router-link :to="{name:'about',params:{user:1}}">登录页面</router-link>

获取的url: :user = 1         
http://localhost:8080/about/1
        
3.注意事项
当定义了params:
注意:{user:1} 中的user 要与路由中的动态参数相同,
例如:params:{user:1}  而 path: '/about/:userid'  如果传递的参数名不同,也会访问到组件,url中是不会携带动态参数的,如果多参数也是这样(/about/:userid/:age/ 不传入age参数也可以访问组件)
        
        
4.获取动态参数  
在访问路由的组件中 就可以获取当前的搜索的全部参数
this.$route.params  // 返回的是一个对象 {'user':1}

查询参数quert

http://127.0.0.01:8080/index?user=1 ...
1.定义路由
{
    path: '/about',
    name: 'about',
    component: () => import('../views/AboutView.vue')  // 异步加载路由,当载路由
}

2.传递查询参数
query:{user:1,可以携带多个查询参数}
<router-link :to="{name:'about',query:{user:1}}">登录页面</router-link>

获取的url: :user = 1         
http://localhost:8080/about?user=1
携带多值的情况下
http://localhost:8080/index/1?user666=1&age=18&sex=1

3.获取查询参数
this.$route.query  返回的结果是个对象

路由属性监听

1.使用监听属性  
watch:{
    "$route"(to,form){
      console.log(to,formform) to新数据(就是点击的新路由)  form 就是旧数据 旧路由
    }
  }
  
2.使用路由中的路由守护(组件)
beforeRouteUpdate(to, from,next) {
    next() // 路由放行
    console.log(from)
    this.msg =  to.params.id
}

编程式导航(使用都是$router对象进行操作的)

想要导航到不同的 URL,可以使用 router.push 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,会回到之前的 URL。

当你点击 <router-link> 时,内部会调用这个方法,所以点击 <router-link :to="..."> 相当于调用 router.push(...) :

声明式							编程式
<router-link :to="...">	   router.push(...)


方式: 可以返回之前的url
// 字符串路径
router.push('/users/eduardo')

// 带有路径的对象
router.push({ path: '/users/eduardo' })

// 命名的路由,并加上参数,让路由建立 url
router.push({ name: 'user', params: { username: 'eduardo' } })

// 带查询参数,结果是 /register?plan=private
router.push({ path: '/register', query: { plan: 'private' } })

// 带 hash,结果是 /about#team
router.push({ path: '/about', hash: '#team' })

使用嵌入 方式
const username = 'eduardo'
// 我们可以手动建立 url,但我们必须自己处理编码
router.push(`/user/${username}`) // -> /user/eduardo
// 同样
router.push({ path: `/user/${username}` }) // -> /user/eduardo
// 如果可能的话,使用 `name` 和 `params` 从自动 URL 编码中获益
router.push({ name: 'user', params: { username } }) // -> /user/eduardo
// `params` 不能与 `path` 一起使用
router.push({ path: '/user', params: { username } }) // -> /user


无记录方式,不能返回之前的url
router.push({ path: '/home', replace: true })
// 相当于
router.replace({ path: '/home' }) // 使用后不会进行记录,不能返回之前的url



跨越历史(页面的向前向后)
// 向前移动一条记录,与 router.forward() 相同
router.go(1)

// 返回一条记录,与router.back() 相同
router.go(-1)

// 前进 3 条记录
router.go(3)

// 如果没有那么多记录,静默失败
router.go(-100)
router.go(100)

// 跳转原网页
 this.$router.push({
            // 从这么进行获取存储的参数 ,进行跳转会原来的页面
            // 因为在login url中存储了一个redirect:原页面的路径
            跳转到当前存储query中的路由中(从哪进入到login页面,跳转时就回到哪里)
            path:this.$route.query.redirect // 跳到原页面了
          })

这些方法可以专门的设置一个button标签进行使用提升用户的体验

路由嵌套

注意:
1.如果 在嵌套路父级路有设置了别名,就会页面进行警告,意思:就是当存在嵌套路由时,不建议给父路由加别名(不要给父路由设置 name别名就可以)
2.动态路由组件表示子组件的结构是不同

路由重定向

{
    path: '/',
    // 方式1:根据命名重定向
    redirect:{name:'index'}
    // 方式2:根据url重定向
    redirect:'/index'
}, 当访问 / 就会重定向到 index路由中 加载指定的组件

路由嵌套

1.路由设置:
通过:一个chidren参数:对应一个数组,内部和正常的设置路由是一样的属于嵌套的子路由列表
{
	path: '/index', 路径地址
	name:'index', 路由别名
	component: () => import('../views/IndexView'),父路由显示组件
    // 嵌套子路由列表参数children
    // 嵌套子路由不需要在前面加入斜杠,因为默认会存在一个斜杠
	children:[
        {
            path:'movie',
            name:"movie",
            component:() => import('组件路径'),
        },
        {
             path:'music',
             name:"music",
             component:() =>import('组件路径'),
        }
    ] 
}

// 在进行嵌套路由时需要对父路由设置 router-view标签作为子路由的出口

2.在IndexView.vue中设置子路由出口
<router-view/> // 子路由的组件会父路由组件中显示
    
3.注意多次嵌套时
1.子级路由path不能加/,否则会找不到组件
2.路由入口要写完整路径,否则会找不到组件
因为如果加了/ 就直接访问到了父路由的上级路由

path: '/index', 路径地址
name:'index', 路由别名
component: () => import('../views/IndexView'),父路由显示组件
嵌套路由参数	
children:[
        {
            path:'/movie',
            name:"movie",
            component:() => import('组件路径'),
        },
        {
             path:'music',
             name:"music",
             component:() =>import('组件路径'),
        }
    ] 
如果嵌套路由添加上了/就不会拼接上父路由地址
url +  / : 127.0.0.1:8080/movie
url : 127.0.0.0:8080/index/music

访问父组件默认展开嵌套路由子组件

// 动态路由组件表示子组件的结构是不同,
// 当访问/index不会渲染任何内容,这是因为没有匹配到合适的子路由
//当访问index路由时,不会对其组件进行渲染,直接匹配到对应component指定的文件中组件中,相当于当访问index就会默认展开当前的MovieView组件
就会实现一下效果
组件使用是不同的
{
    path: '/index',
    component: () => import('../views/IndexView'),
    children:[
        {
            path: '', // 将嵌套的组件path属性路径设置为空,那么当访问父组件时,就会默认展开这个组件
            component: () => import('../views/views_son/MovieView'),
        },
        {
            path:'movie',
            name:"movie",
            component:() => import('../views/views_son/MovieView'),
        },
        {
            path:'music',
            name:"music",
            component:() => import('../views/views_son/MusicView'),
        }
    ]
}

路由的动态绑定(路径不同下的组件复用)

动态绑定绑定是什么:动态的加载路由,使用的组件不同,但是数据不同(组件使用的是相同的)
1.使用的路由是不同的
2.请求的数据是不同的
3.使用的组件是相同的

1.路由的设置
{
    path: '/',
    component: HomeView,
    children: 
    [// 这里面的使用的是共同的子组件
        {
            // 当访问 / 路由是会执行这个的路由进行匹配(默认路由)
            path: '',
            component:()=>import('../views/views_dongtai/MovieDti')
        },
        {
            path: 'azdesc/:id',
            name:'azdesc',
            component:()=>import('../views/views_dongtai/MovieDti') // 使用相同的组件
        },
        {
            path: 'qtdesc/:id',
            name:'qtdesc',
            component:()=>import('../views/views_dongtai/MovieDti') // 使用相同的组件
        },
     ]
},
使用都是相同的组件
    
    
2.设置路由出口显示内容
组件相同,但是路由不同 传入的参数也是不同的
<!--    设置查询参数,传入不同的查询参数-->
<router-link :to="{name:'azdesc',params:{id:'az'}}">安卓</router-link>|
<router-link :to="{name:'qtdesc',params:{id:'qt'}}">其他</router-link>
<router-view></router-view>


3.监听路由中传入的查询参数的不同,获取不同的数据
1.使用created(不行)
// 在组件中 created 页面就会走一次 这个属于销毁创建是才会根据声明周期进行执行
created() {}, //  这种形式 不可行的
    
2.使用监听数据,监听路由对象
// 可以使用监听路由的形式
watch:{ // 通过监听路由的变化,回去对应的查询参数,进行处理 加载的共同组件
        "$route"(to,from){
            // to新数据(就是点击的新路由)
            // form 就是旧数据 旧路由
            console.log(from)
            this.msg = to.params.id // 根据查询参数不同,获取不同数据渲染到组件中
        }
    },
        
3.使用路由守卫进行操作
// 当路由发生变化时,就会进行操作
beforeRouteUpdate(to, from) {
       console.log(from)
       this.msg =  to.params.id
}
如果页面的样式使用的都是一样或者时差不多,就可以使用这种方法,设置公共组件,获取不同的参数

路由传值

通过路由中的props属性确定是否进行传入

方式1: 只获取动态参数
  {
    path:"/show/:user_id", // 携带动态参数
    name:"show",
    props:true, // props当携带存在值就可以在组件中进行获取id值
    component:()=>import('../views/show.vue'),
  }

在show组件中可以通过props进行接受携带的动态参数
props:['user_id']
http://localhost:8080/show/1
user_id 1


方式2: 获取动态参数与查询参数
通过props函数模式模式
  {
    path:"/show/:user_id", // 携带动态参数
    name:"show",
    props:(route)=>({ // 函数方式会接受一个route路由对象
        user_id:route.params.user_id, 动态参数
        age:route.quety.age 查询参选
    })
    component:()=>import('../views/show.vue'),
  }

在show组件中 进行接受
props:["user_id","age"]

http://localhost:8080/show/1?age=18
user_id 1
age 18

router中的keep-alive的缓存使用

主要的作用是保持缓存:保存之前的组件进行切换(组件的保存缓存,不让进行重新组件的创建和销毁)
组件的创建和销毁会浪费性能


使用keep-alive 将组件的出口进行包裹,
就是在声明周期中的激活和停用,相当于将组件缓存,使用时进行激活,切换时就会停用
activated() {
    // 使用后,组件销毁前和销毁后 不会使用
    // 需要配合<keep-alive> 组件 </keep-alive>
    console.log('组件激活')
},
deactivated() {
    console.log('组件停用')
}

重点:可以让router-views渲染的组件进行缓存,不会在进行创建和销毁过程
<keep-alive>
    <router-view></router-view>
</keep-alive>
        
        
        

路由元信息控制权限-导航守卫

官方网址:https://router.vuejs.org/zh/guide/advanced/navigation-guards.html

在前端中的localStroage 进行前端的缓存 和cookie和session一样
使用全局的导航的守卫进行控制(router对象的钩子函数)

1.设置url的权限控制方式
 {
        path: '/url',
        name:'url',
        component: ()=>import('../views/UrlView'),
        children: [
            {
                path: 'index',
                name:'index',
                component:()=>import('../views/views_url/IndexView')
            },
            {
                path: 'login',
                name:'login',
                component:()=>import('../views/views_url/LoginView')
            },
            {
                path: 'smart',
                name:'smart',
                component:()=>import('../views/views_url/SmartView'),
                meta:{
                    // 这个对象的作用,给当前路由做权限的控制
                    auth:true, // 如果为true,就要跳转到登录页面,该组件需要验证,如果是 false那么就不需要验证
                }
            }
        ]
    }
// 当url 中不论是子路由还是父路由 设置上 meta 值后就会进行验证,默认meta为空


2.在全局路由守卫中进行验证 
	1.一般情况下是在存储路由中进行设置的
	2.全局的导航守卫,全部的url都会经过这个方法
    3.接受个参数 to/from  都是route对象 还有一个参数 next
    	 to : 进入的新目标网页 对象
    	 from:离开的旧目标网页 对象
    	 next :这个在全局守卫中必须被调用一次(不调用永远都不会被解析或报错)	     
	4.next() 是可以进行路由跳转{name:'/login'} 或者 '/login'	
    
router.beforeEach( function (to,from,next){
// 在这方法中,需要设置一个匿名的函数,这个 匿名的函数代表就是一个守卫的回调函数
    //  如果设置了meta字段 meta: {auth: true} 就会显示true 代表需要验证
    // 默认 不设置meta 就是空 什么都没有
    //console.log(to.meta.auth) // 可以根据这值进行判断是否需要验证
    if(to.meta.auth){
        // 为true,那么就需要判断(页面需要进行登录验证)
            if ( !localStorage.getItem('user')){
                // 没值,就让它登录,并且携带当前需要登录页面的url/到登录页面
                next({name:'login'})
            }
            next() // 有值 直接放行
    }else {
        // 如果为false 那么就直接放行
         next()
    }
})

在登录页面的登录按钮:
 log() {
            // 存储用户名和密码 保存到前端缓存技术中
            localStorage.setItem('user', {user: this.name, pwd: this.pwd})
            //编程式导航到之前需要登录的页面
            // this.$route.query.redirect 登录之前的旧路由页面
            // 获取当前的携带的url参数:
            this.$router.push({name:'smart'})
        }



重点:如何登录后跳转到原页面,而不是固定页面 
1.在路由守卫中判断localStorage.getItem 中没有值
可以在跳转时,利用查询参数将当前的url传入登录页面中
to.fullPath :就是当前需要验证或者登录的页面的url
next({name:'login',query:{url:to.fullPath}})
2.在登录按钮中编程导航是
let url = this.$route.query.url  //获取到传入的查询参数中的url(就是需要验证登录的url)
this.$router.push(url) //跳转会原页面

404路由与路由的优先级

通过用户输入的路由不存在进行路由的匹配

异步加载的路径方式(性能好,当匹配到才会进行加载,没有匹配就不会加载)
  { //http://localhost:8080/   不存在的路由就会404页面
    path:"*", // * 为通配符
    component:()=>import('../views/404.vue')
  }
  
  http://localhost:8080/#/3213232 访问这个网址就会404页面
  
  同时路由是存在优先级的 从上到下进行匹配,所以404页面不能存放在第一个 要放到最后一个,如果放在第一个就会优先匹配到直接显示404页面

路由通配符

路由通配符的使用
路由
// 通配符路由 * 为通配符
{
    path: "/user-*", // 这个路由可以匹配到user-任何字符
    name: "user-admin",
    component: () => import('../views/user-admin.vue')
},
就会匹配到user-通配符  -后面的全部值
http://localhost:8080/user-admin 匹配到user-admin路由
http://localhost:8080/user-xxx 匹配到user-admin路由
...

当时使用通配符是 user-* 时 $route.params 就会添加一个属性pathMatch
pathMatch 就会匹配到通配符*后面的参数
通配符后面的值admin或者其他全部内容路径内容
this.$route.params.pathMatch // 属性匹配到通配符后面的全部字符

调试模式

在创建的路由对象中添加
 mode:"history" // 可以关闭浏览器url中 #号

导航守卫

全局

导航指的是:路由正在发生 改变
守卫:监视路由的变化
# 完成的导航解析流程
1.导航被触发
2.在失活的组件中调离守卫
3.调用全局的beforeEach守卫
4.在重用组件中调用beforeRouteUpdate守卫(2.2+)
5.在路由配置中调用beforeEnter
6.解析异步路由组件
7.在被激活的组件里面调用beforeRouteEnter
8.调用全局的beforeResolve守卫(2.5+)
9.导航确认
10调用全局钩子 afterEach钩子
11.触发dom更新
12.用创建好的实例调用beforeRouteEnter守卫中传给next的回调函数
next 必须调用要不就会卡在这个位置

作用:
    当/show 路由需要用户登录才能访问,那么就可以 利用全局守卫获取到 对应的用户登录信息,如果登录就可以访问,没有登录需要 用户进行登录后才能访问
    
全局导航守卫:每一次路由进行变化都会调用    
1.路由设置
  {
    path:"/login", // 登录
    name:"login",
    component:()=>import('../views/login.vue')
    
  },
  {
    path:"/notes",  // 笔记 当前路由必须登录才能查看
    name:"notes",
    component:()=>import('../views/notes.vue')
  },
      
2.设置全局守卫 使用router对象进行调用
to: 最新的路由对象 可以看到中的全部参数 query参数 path 参数 等等
from:旧路由对象
next(): 放行 如果不放行,那么就会进行后面的路由组件中 

router.beforeEach((to,from ,next)=>{
	  if(to.path === '/notes'){ // 用户访问笔记路由
        const user = JSON.parse(localStorage.getItem('user'))
        if(user){ // 判断localStorage中是否有用户登录的信息
            next() // 有 放行
        }else{  // 没有 跳转到登录页面
            next({name:"login"})  // 方式1
            next('/login') // 方式2
          }
      }
    next()  // 对其他的路由需要进行放行
}

局部

// 在组件中进行使用的守卫

1. beforRouteEnter 
组件实例之前调用 (用的少)
不能获取组件实例的this 
在渲染该组件的对应路由 confirm前被调用
原因一位当前守卫执行前,组件实例还没有被创建

2.beforRouteUpdate(组件被复用时)
在当前路由变化,但是该组件被复用是进行调用
对于一个带有动态参数 的路由/foo/:id , 在/foo/1和/foo/2之间跳转的时候,由于会渲染同样的foo组件 因此组件实例会被复用而这个钩子就会在这种情况下被调用

beforeRouteUpdate(to,from,next){
// 一定要调用 next 不然就会阻塞整个路由
next()  //相当于对路由的放行
console.log(to.params.id)  // 获取取路由信息
}

2.beforRouteLeave
导航离开时该组件的对应路由时调用
可以访问组件this
在路由离开时,触发这个函数,可以判断某个用户输入的对象,如果对象有值那么就会提示他是否离开,如果没有值,那么就直接放行,提升用户的体验

 // 局部路由守护方法beforRouteLeave用法 提升用户体验
  {
    path:"/eaditor",
    name:"eaditor",
    component:()=>import('../views/eaditor.vue')
  },
当访问这个页面时,才会有这个方法


// 局部的路由守卫方法
beforeRouteLeave(to,from,next){
        //console.log(to); // 当离开这个组件路由时,就会调用这个导航守卫
        if(this.content){
            alert('输入框中存在内容请问需要离开吗')
            next(false) // 表示回复到当前的页面,不进行切换默认失败
        }else{
            next()  // 如果没有内容就进行放行
        }
  }

/user => /about 触发About组件的beforeRouteEnter
/user/1 => /user/2 触发user组件的beforeRouteUpdate

独享路由守卫

    {
        path:'/home',
        component:()=>import('@/components/HomeView'),
        beforeEnter(to, from, next) {
            console.log(to)
            console.log(from)
            next()
        }
    }

子路由组件向父路由组件传值

1.路由设置(嵌套路由下,想要通过子路由组件的值传给父路由组件)
{
    path:'/',
    component:()=>import('@/components/HomeView'),
    children:[
         {
            path:'admin',
            component:()=>import('@/components/AdminView'),
          }
     ]
},
    
2.在子路由组件中设置事件
点击按钮时触发事件,将参数传入

<button @click="child">向父路由传递数据</button>

methods:{
    // 向父路由组件传递参数
    child(){
      // emit('事件名','传递参数')
      this.$emit('func','我是子组件路由的内容值')
    }
}

3.在父组件设置接受
<!-- 通过 @子组件抛出事件名称='父组件下函数方法' 接受子路由组件传递的值    -->
<router-view @func="show"></router-view> // 子组件出口

当子组件点击按钮时,就会触发事件,show方法会被自动调用(只要点击子路由组件的抛出事件的按钮,当前接受的方法事件就会主动触发)
methods: {
    // 会自动的调用当前方法
    show(data) {
      console.log(data,'当前组件是父组件')
    }
}

显示的加载过程

在进入某个路由后 需要从服务器中获取数据,例如在渲染用户信息的时候,你需要从服务器获取 用户数据,两种方式
导航完成之后获取:先完成导航,然后接下来的组件声明周期的钩子中获取数据,在数据获取期间显示加载之类的指示
导航完成之后获取,导航完成前,在路由进行入守卫中获取数据,在数据获取成功后执行导航


导航完成之后获取使用的较多

 <div>
    <!-- 当进行加载数据时(没有加载完成时),就会显示loading, -->
    <!--  当请求后端数据时,就会将loading 变为ture 进行显示loading div -->
    <div v-if="loading" class="loading">loading.....</div>
    <!-- 显示错误信息 -->
    <div v-if="error" class="error">{{ error }}</div>
    <!-- 显示内容 -->
    <div v-if="post">
      <h3>显示内容{{ post.title }}</h3>
      <h3>显示内容{{ post.boby }}</h3>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      post: null,
      error: null,
      loading: false,
    };
  },
  created() {
    // 声明周期获取值
    this.getpostdata(); //在组件加载完成后执行这个方法
  },
  watch:{ // 进行监听 如果路由发生变化就去监听
    $route:"getpostdata" //  当路由发生变化就会请求对应的数据(执行这个函数进行获取最新的数据)
    // 相当于$route: getpostdata()
  },
  methods: {
    async getpostdata() {
      // 异步加载方式
      try {
        this.loading = true; // 在 数据请求的一瞬间,前进行显示请求表示,如果数据少看不到,数据多就能看到
        const { data } = await this.$https.get("/api...."); // 请求这个值,利用结构获取data
        this.loading = false // 将loading 赋值为false  请求完毕了不在显示
        this.post = data;
      } catch(error) {
        this.error = error.toString() // 将错误信息转为字符串
      }
    },
  },
};
</script>