Vue3的Vue-Router基础

本节介绍了Vue3的Vue-Router的基础内容,包括安装、创建、动态路由、获取参数、路由切换、历史模式、导航守卫,并与Vue2.x的区别做出代码展示

1、Vue-Router的安装及作用

通过路由系统将 组件 与可访问的url绑定在一起,
路由设计的目的:切换页面时让url路径变化,不触发HTML物理文件的加载,因此VueRouter的跳页模式不能使用普通的超链接方式

npm install vue-router --save  //Vue2.x的安装方式,--save保存到依赖
npm install vue-router@next --save 或 npm install vue-router@4   // Vue3.x的安装方式
2、Vue-Router 创建
1) Vue3.x是使用 createRouter() 方法来创建的,
/*在main.js中*/
import router from './router/index.js'
app.use(router)
/*在index.js中*/
import {createRouter, createWebHistory,createWebHashHistory} from 'vue-router'
const router = createRouter({
    history: createWebHistory(),  //hash模式:createWebHashHistory,history模式:createWebHistory
    routes: []
})
export default router
2) Vue2.x是通过 new Router() 方法来创建路由的,
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const router = new VueRouter({
  	routes: []
});
export default router;
3、动态路由
//Vue3.x写法
//添加路由
router.addRouter({path:'/one',name:'one',component:()=> import('...page1.vue')}) 
//添加子路由
router.addRouter('one',{path:'/son1',name:'son1',component:()=> import('...son1.vue')})
//Vue2.x写法
let routeA=[{ path: '/pageA', name: 'pageA',  component:()=> import('...pageA.vue')}]
router.addRoutes(routeA);
4、路由匹配及404页面
const routes = [
    { path:'/article/:id(\\d+)',//正则匹配,仅匹配数字
      component:article  },
    { path:'/films/:id?',       //正则匹配,'+'至少需要一个;'*'0或多个;'?'有或者没有,不可重复
      component:films  },
    { path:"/:path(.*)", 	    //404页面路由
      component:NotFound  },
]
5、获取路由参数
//Vue3.x
import { useRoute,useRouter } from 'vue-router';
const route = useRoute();
const router = useRouter();
const id = route.query.id
const title = route.meta.title   //获取路由名称,可用于面包屑
//const path = router.push()
//Vue2.x
this.$route.query.id

请添加图片描述

注:$route:获取路由信息对象,只读; $router:操作路由对象 ,只写。

6、切换路由
1)使用router-link
<router-link to="/">首页</router-link>    //Vue3.x与Vue2.x写法一致
2)编程式导航 router.push()、router.replace()、router.go()、router.resolve()
  1. router.push({}) 可回退
  2. router.replace(‘/’) 替换页面不能回退
  3. router.resolve()返回路由地址的标准化模板
    使用:
let router = this.$router.resolve({
  path: '/home',
  query:{id:item.id}
})
window.open(router.href,'_blank')  //路由跳转重新打开一个页面
//Vue3.x写法
import { useRouter }  from  'vue-router'
setup(){
    const  router = useRouter()
    router.push('/');
    //携带参数跳转
    router.push({path:'/news/123'})
    router.push({name:'news',params:{id:3435}})
    router.push({path:"/",query:{search:'特朗普'}}
    router.replace('/')  //替换页面,不能回退
    router.go(1)  		 //前进一页
    router.go(-1) 		 //后退一页
}
//Vue2.x写法
this.$router.push({path: '/bbb', query: {username: "abc"}});//$router.push()、$router.replace()、$router.go()
3)route与router的区别
$router:路由操作对象
$route:路由信息对象,路由参数的接收

this.$router.push("/user/list");
this.$router.push({name:'role'})
this.$router.push({name:'role-operate',params: {id: row.roleId }})
this.$router.push({name:'role-operate',params:{id:0}})

//在vue3中
//模板使用
$route.path 、$route.name
//在script中使用
import { useRoute,useRouter } from 'vue-router';
const route = useRoute();
const router = useRouter();
const path = route.path
const title = route.meta.title
7、命名式路由
//写在App.vue
<router-view name="shopTop"></router-view>
<router-view></router-view>
<router-view name="shopFooter"></router-view>
//写在router的index.js
{	 path:'/shop',
    components:{
        default:shopMain,
        shopTop:shopTop,
        shopFooter:shopFooter}
}
8、重定向与别名
{  //重定向
    path:'/mail',
    redirect:'/shop',
    // redirect:to=>{return {path:'/shop'}} //函数式
}
{  //取别名
    path:'/shop',
    // alias:"/wlshop",             		//一个别名
    alias:["/wlshop","/wl22shop"],  		//多个别名用数组表示
    components:{shopMain }
},
9、hash 与 history 模式 、js代码实现原理

VueRouter为了支持单页面应用的页面管理和页面跳转,提供hash与history两种模式

// Vue2.x的两种模式
mode: 'history'
mode: 'hash'
// Vue3.x的两种模式
history: createWebHistory()
history:createWebHashHistory()

注:Vue3.x的模式是一个方法,而不是一个变量,不然会报这样的错误: Cannot use ‘in’ operator to search for ‘path’ in undefined。
两者模式的区别
①hash模式
使用锚点技术重写URL访问路径,在原有URL路径后拼接/#/xxx,不重新加载原有HTML文件的基础上,实现切换URL路径的目的,实现原理:使用onhashchange

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .page{ width:400px;height:400px}
        .index{background-color: #42b983;display: none;}
        .about{background-color: #f37873;display: none;}
        .third{ background-color: #EEE111;display: none;}
    </style>
</head>
<body>
    <a href="#/index" >访问首页</a>
    <a href="#/about">关于页面</a>
    <div class="page index">我是首页</div>
    <div class="page about">关于页面</div>
    <div class="page third">第三个页面</div>
    <script type="text/javascript">
        window.onhashchange = function (event) {  //url的hash部分切换事件
          var newURL = event.newURL.split('#/')[1]   //获取要跳转的url路径并截取页面名称
          var oldURL = event.oldURL.split('#/')[1]   //获取跳转时的起点页面路径并截取页面名称
          var newPage = document.querySelector('.'+newURL)   //获取两个页面的dom名称
          var oldPage =  document.querySelector('.'+oldURL)
          newPage.style.display = 'block'   //显示目标页面
          oldPage.style.display = 'none'    //隐藏当前页面
        }
    </script>
</body>
</html>

hsah模式利用纯静态技术,不触发网页重新加载情况下切换url路径,配合onhashchange()实现,hssh部分发生变化,触发函数,通过JS编程实现DOM对象切换展示。

不足:

  • 在分布式微前端中,嵌套的子应用与主应用都使用hash模式时,由于hash模式的url路径只能有一个#,导致子应用与主应用在定义url路径存在困难
  • hash模式的url路径包含#,视觉上不美观

②history模式
不使用锚点技术重写URL路径,history的 url 不存在#,在视觉上更加美观
采用history对象中的pushState()函数重写URL路径,在触发重新加载的情况下变更URL路径,
需要服务器的重定向
原理是:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>history</title>
    <style>
        .page{ width:400px;height:400px}
        .index{background-color: #42b983;display: none;}
        .about{background-color: #f37873;display: none;}
        .third{ background-color: #EEE111;display: none;}
    </style>
</head>
<body>
<a href="javascript:jump('/index')" >首页</a>
<a href="javascript:jump('./about')">关于页面</a>
<a href="javascript:jump('./third')">第三个</a>
<div class="page index">我是首页</div>
<div class="page about">关于页面</div>
<div class="page third">第三个页面</div>
<script type="text/javascript">
    function jump(path) {
      history.pushState(null,'page',path)    //重写URL路径为超链接传入的名称
      var pages = document.querySelector('.page')   //获取所有页面组件
      var newPage = document.querySelector(path.replace('/','.'))  //获取指定跳转的目标页面对象
      pages.forEach(item=> item.style.display = 'none')   //隐藏其他页面
      newPage.style.display = 'block'   //展示跳转的页面
    }
</script>
</body>
</html>

history模式重写URL的解决方案是javascript:jump,导致的问题是新路径不包含原有HTML物理文件的访问地址,一旦刷新网页会造成404,VueCli在开发环境中解决了history模式刷新问题,但在生产环境下,还需要配合服务器转发重定向。

10、导航守卫

路由守卫就是路由跳转过程中的一些钩子函数,在路由跳转的时候,做一些判断或其他的操作。类似于组件生命周期钩子函数。

1) Vue3.x未改变部分

beforeEach前置守卫,beforeResolve 路由解析前,afterEach 路由跳转后执行
分类

//(1).全局路由守卫
beforeEach(to,form,next)全局前置守卫,路由跳转前触发。
beforeResolve(to,from,next)全局解析守卫在所有组件内守卫被解析后触发。
AfterEach(to,from)全局后置守卫,路由跳转完成后触发。
//(2).路由独享守卫
beforeEnter(to,from,next) 路由对象单个路由配置 ,单个路由进入前触发。
//(3).组件路由守卫
beforeRouteEnter(to,from,next)在组件生命周期 beforeCreate 阶段触发。
beforeRouteUpdate(to,from,next)当前路由改变时触发。
beforeRouteLeave(to,from,next)导航离开该组件的对应路由时触发。
//beforeEnter路由独享的守卫
{	path:'/page',   //在路由配置上定义
    component:page,
    beforeEnter:(to,from)=>{console.log('beforeEnter')}
},
//beforeEach前置守卫,看用户有没有权限跳转到对应的页面
router.beforeEach((to, from,next) => {
    console.log('to-from',to,from)
    next()
    // return false 返回 false 以取消导航
})
//beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave(生命周期钩子) 
beforeRouteEnter((to, from, next)=>{}) 

项目使用的路由守卫

通过 beforeEach 设置登录后获取用户可进入跳转权限

当用户访问登录或者404页面可直接跳转

if(to.name==='login'||to.name === '404'){
	next()
}

从 store 状态管理中获取用户登录后用户 token

引入store状态管理

import store from '@/store'

获取状态管理中用户 token

Const auth:any = store.state
Const isLogin = !!Auth.authstore.token

当存在 token 时,先判断用户是否存在路由权限后请求用户的路由权限。

if (isLogin) {
      if (auth.authStore.routerPermission.length === 0) {
        getRouterList().then(({ data }) => {
          store.dispatch('authStore/setRouterPermission', data)
          if (data.length === 0)
            next({ name: 'Login', query: { redirect: to.fullPath } })
          } else {
            if (from.path === '/login' || to.path === '/') {
              next({ name: data[0].name })
            } else {
              next()
            }
          }
        })
     }
}else{}
2) Vue3.x新增(组件内的守卫)

onBeforeRouteEnter,onBeforeRouteUpdate,onBeforeRouteLeave

onBeforeRouteLeave((to, from, next)=>{   //根据Vue3.x提供的生命周期钩子
    const bool = window.confirm('你确定要离开当前页面吗?');
  	 if(!bool) {  return  false }
})
11、监听路由变化
//Vue3.x写法
import { useRoute }  from  'vue-router'
setup(){
    const route = useRoute();
    watch(route.query,(query)=>{ console.log(query); })
}
//Vue2.x写法
watch:{
      '$route.path':function(newVal,oldVal){}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值