vue-router路由(二)

​🌈个人主页:前端青山
🔥系列专栏:Vue篇
🔖人终将被年少不可得之物困其一生

依旧青山,本期给大家带来vue篇专栏内容:vue-router路由(二)

目录

1. Vue-Router 的懒加载如何实现

2. 路由的hash和history模式的区别

1. hash模式

2. history模式

3. 两种模式对比

3. 如何获取页面的hash变化

4. $route 和$router 的区别

5. 如何定义动态路由?如何获取传过来的动态参数?

6. Vue-router 路由钩子在生命周期的体现

7. Vue-router跳转和location.href有什么区别

8. params和query的区别

9. Vue-router 导航守卫有哪些

10. 对前端路由的理解

1. Vue-Router 的懒加载如何实现

非懒加载:

import List from '@/components/list.vue'
const router = new VueRouter({
  routes: [
    { path: '/list', component: List }
  ]
})

(1)方案一(常用):使用箭头函数+import动态加载

const List = () => import('@/components/list.vue')
const router = new VueRouter({
  routes: [
    { path: '/list', component: List }
  ]
})

(2)方案二:使用箭头函数+require动态加载

const router = new Router({
  routes: [
   {
     path: '/list',
     component: resolve => require(['@/components/list'], resolve)
   }
  ]
})

(3)方案三:使用webpack的require.ensure技术,也可以实现按需加载。 这种情况下,多个路由指定相同的chunkName,会合并打包成一个js文件。

// r就是resolve
const List = r => require.ensure([], () => r(require('@/components/list')), 'list');
// 路由也是正常的写法  这种是官方推荐的写的 按模块划分懒加载 
const router = new Router({
  routes: [
  {
    path: '/list',
    component: List,
    name: 'list'
  }
 ]
}))

2. 路由的hash和history模式的区别

Vue-Router有两种模式:hash模式history模式。默认的路由模式是hash模式。

1. hash模式

简介: hash模式是开发中默认的模式,它的URL带着一个#,例如:www.abc.com/#/vue,它的hash值就是#/vue

特点:hash值会出现在URL里面,但是不会出现在HTTP请求中,对后端完全没有影响。所以改变hash值,不会重新加载页面。这种模式的浏览器支持度很好,低版本的IE浏览器也支持这种模式。hash路由被称为是前端路由,已经成为SPA(单页面应用)的标配。

原理: hash模式的主要原理就是onhashchange()事件

window.onhashchange = function(event){
    console.log(event.oldURL, event.newURL);
    let hash = location.hash.slice(1);
}

使用onhashchange()事件的好处就是,在页面的hash值发生变化时,无需向后端发起请求,window就可以监听事件的改变,并按规则加载相应的代码。除此之外,hash值变化对应的URL都会被浏览器记录下来,这样浏览器就能实现页面的前进和后退。虽然是没有请求后端服务器,但是页面的hash值和对应的URL关联起来了。

2. history模式

简介: history模式的URL中没有#,它使用的是传统的路由分发模式,即用户在输入一个URL时,服务器会接收这个请求,并解析这个URL,然后做出相应的逻辑处理。 特点: 当使用history模式时,URL就像这样:abc.com/user/id。相比hash模式更加好看。但是,history模式需要后台配置支持。如果后台没有正确配置,访问时会返回404。 API: history api可以分为两大部分,切换历史状态和修改历史状态:

  • 修改历史状态:包括了 HTML5 History Interface 中新增的 pushState()replaceState() 方法,这两个方法应用于浏览器的历史记录栈,提供了对历史记录进行修改的功能。只是当他们进行修改时,虽然修改了url,但浏览器不会立即向后端发送请求。如果要做到改变url但又不刷新页面的效果,就需要前端用上这两个API。

  • 切换历史状态: 包括forward()back()go()三个方法,对应浏览器的前进,后退,跳转操作。

虽然history模式丢弃了丑陋的#。但是,它也有自己的缺点,就是在刷新页面的时候,如果没有相应的路由或资源,就会刷出404来。

如果想要切换到history模式,就要进行以下配置(后端也要进行配置):

const router = new VueRouter({
  mode: 'history',
  routes: [...]
})
3. 两种模式对比

调用 history.pushState() 相比于直接修改 hash,存在以下优势:

  • pushState() 设置的新 URL 可以是与当前 URL 同源的任意 URL;而 hash 只可修改 # 后面的部分,因此只能设置与当前 URL 同文档的 URL;

  • pushState() 设置的新 URL 可以与当前 URL 一模一样,这样也会把记录添加到栈中;而 hash 设置的新值必须与原来不一样才会触发动作将记录添加到栈中;

  • pushState() 通过 stateObject 参数可以添加任意类型的数据到记录中;而 hash 只可添加短字符串;

  • pushState() 可额外设置 title 属性供后续使用。

  • hash模式下,仅hash符号之前的url会被包含在请求中,后端如果没有做到对路由的全覆盖,也不会返回404错误;history模式下,前端的url必须和实际向后端发起请求的url一致,如果没有对用的路由处理,将返回404错误。

hash模式和history模式都有各自的优势和缺陷,还是要根据实际情况选择性的使用。

3. 如何获取页面的hash变化

(1)监听$route的变化

// 监听,当路由发生变化的时候执行
watch: {
  $route: {
    handler: function(val, oldVal){
      console.log(val);
    },
    // 深度观察监听
    deep: true
  }
},

(2)window.location.hash读取#值 window.location.hash 的值可读可写,读取来判断状态是否改变,写入时可以在不重载网页的前提下,添加一条历史访问记录。

4. $route 和$router 的区别

  • $route 是“路由信息对象”,包括 path,params,hash,query,fullPath,matched,name 等路由信息参数

  • $router 是“路由实例”对象包括了路由的跳转方法,钩子函数等。

5. 如何定义动态路由?如何获取传过来的动态参数?

(1)param方式

  • 配置路由格式:/router/:id

  • 传递的方式:在path后面跟上对应的值

  • 传递后形成的路径:/router/123

1)路由定义

//在APP.vue中
<router-link :to="'/user/'+userId" replace>用户</router-link>    
​
//在index.js
{
   path: '/user/:userid',
   component: User,
},

2)路由跳转

// 方法1:
<router-link :to="{ name: 'users', params: { uname: wade }}">按钮</router-link
​
// 方法2:
this.$router.push({name:'users',params:{uname:wade}})
​
// 方法3:
this.$router.push('/user/' + wade)

3)参数获取 通过 $route.params.userid 获取传递的值

(2)query方式

  • 配置路由格式:/router,也就是普通配置

  • 传递的方式:对象中使用query的key作为传递方式

  • 传递后形成的路径:/route?id=123

1)路由定义

//方式1:直接在router-link 标签上以对象的形式
<router-link :to="{path:'/profile',query:{name:'why',age:28,height:188}}">档案</router-link>
​
// 方式2:写成按钮以点击事件形式
<button @click='profileClick'>我的</button>    
​
profileClick(){
  this.$router.push({
    path: "/profile",
    query: {
        name: "kobi",
        age: "28",
        height: 198
    }
  });
}

2)跳转方法

// 方法1:
<router-link :to="{ name: 'users', query: { uname: james }}">按钮</router-link>
​
// 方法2:
this.$router.push({ name: 'users', query:{ uname:james }})
​
// 方法3:
<router-link :to="{ path: '/user', query: { uname:james }}">按钮</router-link>
​
// 方法4:
this.$router.push({ path: '/user', query:{ uname:james }})
​
// 方法5:
this.$router.push('/user?uname=' + jsmes)

3)获取参数

通过$route.query 获取传递的值

6. Vue-router 路由钩子在生命周期的体现

一、Vue-Router导航守卫

有的时候,需要通过路由来进行一些操作,比如最常见的登录权限验证,当用户满足条件时,才让其进入导航,否则就取消跳转,并跳到登录页面让其登录。 为此有很多种方法可以植入路由的导航过程:全局的,单个路由独享的,或者组件级的

  1. 全局路由钩子

vue-router全局有三个路由钩子;

  • router.beforeEach 全局前置守卫 进入路由之前

  • router.beforeResolve 全局解析守卫(2.5.0+)在 beforeRouteEnter 调用之后调用

  • router.afterEach 全局后置钩子 进入路由之后

具体使用∶

  • beforeEach(判断是否登录了,没登录就跳转到登录页)

router.beforeEach((to, from, next) => {  
    let ifInfo = Vue.prototype.$common.getSession('userData');  // 判断是否登录的存储信息
    if (!ifInfo) { 
        // sessionStorage里没有储存user信息    
        if (to.path == '/') { 
            //如果是登录页面路径,就直接next()      
            next();    
        } else { 
            //不然就跳转到登录      
            Message.warning("请重新登录!");     
            window.location.href = Vue.prototype.$loginUrl;    
        }  
    } else {    
        return next();  
    }
})
  • afterEach (跳转之后滚动条回到顶部)

router.afterEach((to, from) => {  
    // 跳转之后滚动条回到顶部  
    window.scrollTo(0,0);
});
  1. 单个路由独享钩子

beforeEnter 如果不想全局配置守卫的话,可以为某些路由单独配置守卫,有三个参数∶ to、from、next

export default [    
    {        
        path: '/',        
        name: 'login',        
        component: login,        
        beforeEnter: (to, from, next) => {          
            console.log('即将进入登录页面')          
            next()        
        }    
    }
]
  1. 组件内钩子

beforeRouteUpdate、beforeRouteEnter、beforeRouteLeave

这三个钩子都有三个参数∶to、from、next

  • beforeRouteEnter∶ 进入组件前触发

  • beforeRouteUpdate∶ 当前地址改变并且改组件被复用时触发,举例来说,带有动态参数的路径foo/∶id,在 /foo/1 和 /foo/2 之间跳转的时候,由于会渲染同样的foa组件,这个钩子在这种情况下就会被调用

  • beforeRouteLeave∶ 离开组件被调用

注意点,beforeRouteEnter组件内还访问不到this,因为该守卫执行前组件实例还没有被创建,需要传一个回调给 next来访问,例如:

beforeRouteEnter(to, from, next) {      
    next(target => {        
        if (from.path == '/classProcess') {          
            target.isFromProcess = true        
        }      
    })    
}

二、Vue路由钩子在生命周期函数的体现

  1. 完整的路由导航解析流程(不包括其他生命周期)

  • 触发进入其他路由。

  • 调用要离开路由的组件守卫beforeRouteLeave

  • 调用局前置守卫∶ beforeEach

  • 在重用的组件里调用 beforeRouteUpdate

  • 调用路由独享守卫 beforeEnter。

  • 解析异步路由组件。

  • 在将要进入的路由组件中调用 beforeRouteEnter

  • 调用全局解析守卫 beforeResolve

  • 导航被确认。

  • 调用全局后置钩子的 afterEach 钩子。

  • 触发DOM更新(mounted)。

  • 执行beforeRouteEnter 守卫中传给 next 的回调函数

  1. 触发钩子的完整顺序

路由导航、keep-alive、和组件生命周期钩子结合起来的,触发顺序,假设是从a组件离开,第一次进入b组件∶

  • beforeRouteLeave:路由组件的组件离开路由前钩子,可取消路由离开。

  • beforeEach:路由全局前置守卫,可用于登录验证、全局路由loading等。

  • beforeEnter:路由独享守卫

  • beforeRouteEnter:路由组件的组件进入路由前钩子。

  • beforeResolve:路由全局解析守卫

  • afterEach:路由全局后置钩子

  • beforeCreate:组件生命周期,不能访问tAis。

  • created;组件生命周期,可以访问tAis,不能访问dom。

  • beforeMount:组件生命周期

  • deactivated:离开缓存组件a,或者触发a的beforeDestroy和destroyed组件销毁钩子。

  • mounted:访问/操作dom。

  • activated:进入缓存组件,进入a的嵌套子组件(如果有的话)。

  • 执行beforeRouteEnter回调函数next。

  1. 导航行为被触发到导航完成的整个过程

  • 导航行为被触发,此时导航未被确认。

  • 在失活的组件里调用离开守卫 beforeRouteLeave。

  • 调用全局的 beforeEach守卫。

  • 在重用的组件里调用 beforeRouteUpdate 守卫(2.2+)。

  • 在路由配置里调用 beforeEnteY。

  • 解析异步路由组件(如果有)。

  • 在被激活的组件里调用 beforeRouteEnter。

  • 调用全局的 beforeResolve 守卫(2.5+),标示解析阶段完成。

  • 导航被确认。

  • 调用全局的 afterEach 钩子。

  • 非重用组件,开始组件实例的生命周期:beforeCreate&created、beforeMount&mounted

  • 触发 DOM 更新。

  • 用创建好的实例调用 beforeRouteEnter守卫中传给 next 的回调函数。

  • 导航完成

7. Vue-router跳转和location.href有什么区别

  • 使用 location.href= /url来跳转,简单方便,但是刷新了页面;

  • 使用 history.pushState( /url ) ,无刷新页面,静态跳转;

  • 引进 router ,然后使用 router.push( /url ) 来跳转,使用了 diff 算法,实现了按需加载,减少了 dom 的消耗。其实使用 router 跳转和使用 history.pushState() 没什么差别的,因为vue-router就是用了 history.pushState() ,尤其是在history模式下。

8. params和query的区别

用法:query要用path来引入,params要用name来引入,接收参数都是类似的,分别是 this.$route.query.namethis.$route.params.name

url地址显示:query更加类似于ajax中get传参,params则类似于post,说的再简单一点,前者在浏览器地址栏中显示参数,后者则不显示

注意:query刷新不会丢失query里面的数据 params刷新会丢失 params里面的数据。

9. Vue-router 导航守卫有哪些

  • 全局前置/钩子:beforeEach、beforeResolve、afterEach

  • 路由独享的守卫:beforeEnter

  • 组件内的守卫:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave

10. 对前端路由的理解

在前端技术早期,一个 url 对应一个页面,如果要从 A 页面切换到 B 页面,那么必然伴随着页面的刷新。这个体验并不好,不过在最初也是无奈之举——用户只有在刷新页面的情况下,才可以重新去请求数据。

后来,改变发生了——Ajax 出现了,它允许人们在不刷新页面的情况下发起请求;与之共生的,还有“不刷新页面即可更新页面内容”这种需求。在这样的背景下,出现了 SPA(单页面应用)。

SPA极大地提升了用户体验,它允许页面在不刷新的情况下更新页面内容,使内容的切换更加流畅。但是在 SPA 诞生之初,人们并没有考虑到“定位”这个问题——在内容切换前后,页面的 URL 都是一样的,这就带来了两个问题:

  • SPA 其实并不知道当前的页面“进展到了哪一步”。可能在一个站点下经过了反复的“前进”才终于唤出了某一块内容,但是此时只要刷新一下页面,一切就会被清零,必须重复之前的操作、才可以重新对内容进行定位——SPA 并不会“记住”你的操作。

  • 由于有且仅有一个 URL 给页面做映射,这对 SEO 也不够友好,搜索引擎无法收集全面的信息

为了解决这个问题,前端路由出现了。

前端路由可以帮助我们在仅有一个页面的情况下,“记住”用户当前走到了哪一步——为 SPA 中的各个视图匹配一个唯一标识。这意味着用户前进、后退触发的新内容,都会映射到不同的 URL 上去。此时即便他刷新页面,因为当前的 URL 可以标识出他所处的位置,因此内容也不会丢失。

那么如何实现这个目的呢?首先要解决两个问题:

  • 当用户刷新页面时,浏览器会默认根据当前 URL 对资源进行重新定位(发送请求)。这个动作对 SPA 是不必要的,因为我们的 SPA 作为单页面,无论如何也只会有一个资源与之对应。此时若走正常的请求-刷新流程,反而会使用户的前进后退操作无法被记录。

  • 单页面应用对服务端来说,就是一个URL、一套资源,那么如何做到用“不同的URL”来映射不同的视图内容呢?

从这两个问题来看,服务端已经完全救不了这个场景了。所以要靠咱们前端自力更生,不然怎么叫“前端路由”呢?作为前端,可以提供这样的解决思路:

  • 拦截用户的刷新操作,避免服务端盲目响应、返回不符合预期的资源内容。把刷新这个动作完全放到前端逻辑里消化掉。

  • 感知 URL 的变化。这里不是说要改造 URL、凭空制造出 N 个 URL 来。而是说 URL 还是那个 URL,只不过我们可以给它做一些微小的处理——这些处理并不会影响 URL 本身的性质,不会影响服务器对它的识别,只有我们前端感知的到。一旦我们感知到了,我们就根据这些变化、用 JS 去给它生成不同的内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/148316.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

精益管理3个阶段,如何实现高效企业管理?

在现今竞争激烈的市场环境下&#xff0c;企业需要不断提高经营效率和降低成本来保持竞争力。其中&#xff0c;精益管理是一种不错的管理方式&#xff0c;在各大企业得到广泛的运用。今天我们来了解一下精益管理的3个阶段&#xff0c;以及如何使用精益管理工具来实现高效企业管理…

ubuntu20安装opencv4和opencv_contrib 多版本共存

openCV 卸载 openCV 安装后的源码尽可能保留&#xff0c;因为可以直接从build文件夹下卸载已经安装的openCV. 参考链接&#xff1a;视觉学习笔记10——opencv的卸载、安装与多版本管理 如果已经安装完openCV,后续想重新装&#xff0c;需要先卸载掉安装的openCV. 在ubuntu终端…

实验室EM3电磁铁

锦正茂EM3电磁铁&#xff0c;可以通过更换电磁铁极头在一定范围内改善磁场的大小和磁场的均匀度 &#xff0c;并且可以通过调整极头间距改变磁场的大小。主要用于磁滞现象研究、磁化系数测量、霍尔效应研究、磁光实验、磁场退火、核磁共振、电子顺磁共振、生物学研究、磁性测量…

【JavaEE】Servlet API 详解(HttpServletResponse类方法演示、实现自动刷新、实现自动重定向)

一、HttpServletResponse HttpServletResponse表示一个HTTP响应 Servlet 中的 doXXX 方法的目的就是根据请求计算得到相应, 然后把响应的数据设置到 HttpServletResponse 对象中 然后 Tomcat 就会把这个 HttpServletResponse 对象按照 HTTP 协议的格式, 转成一个字符串, 并通…

【邻接矩阵】

文章目录 邻接矩阵 图的逻辑结构&#xff1a;多对多。 图没有顺序存储结构&#xff0c;但可以借助二维数组来表示元素间的关系。 数组表示法&#xff08;邻接矩阵&#xff09;。 多重链表&#xff1a;邻接表&#xff0c;邻接多重表&#xff0c;十字链表。 邻接矩阵&#xff08;…

Canvas—从入门到案例实现

文章目录 Canvas—从入门到案例实现一、设置canvas环境1.1 <canvas>元素1.2 渲染上下文context 二、形状与路径的绘制2.1 形状绘制2.2 路径绘制2.3 绘制一个笑脸 三、使用样式和颜色四、绘制文本五、使用图像5.1 图片源5.2 获取页面内的图片5.3 缩放Scaling5.4 切片Slici…

深度学习+opencv+python实现车道线检测 - 自动驾驶 计算机竞赛

文章目录 0 前言1 课题背景2 实现效果3 卷积神经网络3.1卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV56 数据集处理7 模型训练8 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &am…

Vue3使用i18n国际化

安装 npm install vue-i18nnext 创建i18n文件夹 我这个项目是中、俄语言切换 zh.ts里放中文语言下要显示的字段&#xff0c;rn.ts里放俄语要显示的字段 index.ts import { createI18n } from vue-i18n; import ZH from ./zh.js; import RN from ./rn.js; const messages {zh…

远程创建分支本地VScode看不到分支

在代码存放处右击&#xff0c;点击Git Bash Here 输入git fetch–从远程仓库中获取最新的分支代码和提交历史 就OK啦&#xff0c;现在分支可以正常查看了

【SpringBoot3+Vue3】二【实战篇】-后端

目录 一、环境搭建 1、数据库脚本 2、pom 3、yml 4、通过mybatis-X生成实体pojo等 4.1 Article 4.2 Category 4.3 User 5、 Mapper 5.1 ArticleMapper 5.2 CategoryMapper 5.3 UserMapper 6、service 6.1 ArticleService 6.2 CategoryService 6.3 UserService …

使用亚马逊鲲鹏系统有什么好处?

亚马逊鲲鹏系统是一款能绕过亚马逊智能检测&#xff0c;完全模拟人类真实行为&#xff0c;通过模拟真实的人流量来帮助你提升你的产品排名&#xff0c;让你的产品出现在搜索首页&#xff0c;从而快速帮助提高销售业绩的营销工具&#xff01; 好处1&#xff1a;自动化操作更节约…

Fabric多机部署启动节点与合约部署

这是我搭建的fabric的网络拓扑 3 个 orderer 节点&#xff1b;组织 org1 , org1 下有两个 peer 节点&#xff0c; peer0 和 peer1; 组织 org2 , org2 下有两个 peer 节点&#xff0c; peer0 和 peer1; 以上是我的多机环境的网络拓扑&#xff0c;使用的是docker搭建的。我的网络…

什么是数据泄露?泄露途径有哪些?企业如何免遭数据泄露?

数据泄露指将机密信息、私人信息或其他敏感信息发布到不安全的环境中。数据泄露可能由意外引起&#xff0c;也可能是蓄意攻击的结果。 每年都有数百万人卷入数据泄露&#xff0c;包括意外看错病人图表的医生&#xff0c;以及大规模尝试访问政府计算机以发现敏感信息。 因为敏…

向量矩阵范数pytorch

向量矩阵范数pytorch 矩阵按照某个维度求和&#xff08;dim就是shape数组的下标&#xff09;1. torch1.1 Tensors一些常用函数 一些安装问题cd进不去不去目录PyTorch里面_表示重写内容 在默认情况下&#xff0c;PyTorch会累积梯度&#xff0c;我们需要清除之前的值 范数是向量或…

企业级真实应用利用Mybatis-Plus进行分页查询处理

怎么导入依赖我在之前的文章里边有说过不理解的可以看看 你应该懂点Mybatis-plus&#xff0c;真的好用 1&#xff1a;了解Page<T>类的使用 首先我们需要使用到Page类 &#xff0c;建立一个Page类&#xff0c;泛式类型中放入我们需要输出的类&#xff0c;是列表的话就…

分享5款好用到爆的神仙软件

​ 最近陆陆续续收到好多小伙伴的咨询&#xff0c;这边也是抓紧时间整理出几个好用的软件&#xff0c;希望可以帮到大家。 1.全局鼠标手势——MouseInc ​ MouseInc是一款由shuax制作的全局鼠标手势软件&#xff0c;还支持很多增强辅助功能&#xff0c;如屏幕取色、窗口管理、…

前端学习笔记--Event-loop

定义 Event Loop&#xff1a;即事件循环&#xff0c;是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制&#xff0c;也就是我们经常使用异步的原理。 **进程&#xff1a;**进程是计算机中的程序关于某数据集合上的一次运行活动&#xff0c;是系统进行资源分…

vmware安装MacOS以及flutter遇到的问题

安装过程&#xff1a;参考下面的文章 链接&#xff1a; 虚拟机VMware安装苹果系统macOS&#xff0c;超级详细教程&#xff0c;附文件下载&#xff0c;真教程&#xff01;&#xff01; 无限重启情况&#xff1a; &#xff08;二&#xff09; 配置虚拟机找到你的虚拟机安装文件…

查询站点真实IP地址,绕过CDN

一.如何判断站点是否使用了CDN&#xff1f; 使用其他省市的电脑进行ping看返回的IP地址是否相同通过第三方网站查询 站长工具 3.nslookup命令 二. 如何绕过CDN获取真实IP 子域名查询&#xff0c;因为很多站点只对主域名进行了CDN加速网站邮件头信息微步在线DNS查询

[PyTorch][chapter 63][强化学习-QLearning]

前言&#xff1a; 这里结合走迷宫的例子,重点学习一下QLearning迭代更新算法 0,1,2,3,4 是房间&#xff0c;之间绿色的是代表可以走过去。 5为出口 可以用下图表示 目录&#xff1a; 策略评估 策略改进 迭代算法 走迷宫实现Python 一 策略评估 强化学习最终是为了…