!
也想出现在这里? 联系我们
广告位
当前位置:首页>运营>网站运维>Vue.js前端路由和异步组件介绍(vue3.0异步组件)

Vue.js前端路由和异步组件介绍(vue3.0异步组件)

针对react/vue能够根据业务需求口喷router的关键配置,包括但不限于:路由的匹配规则、路由守卫、路由分层等;能够描述清楚history的主要模式,知道historyrouter的边界;

Vue.js前端路由和异步组件介绍(vue3.0异步组件)

P6+ ~ P7

在没有路由的情况下,也可以根据也无需求,实现一个简单的路由;读过router底层的源码,不要求每行都读,可以口喷关键代码即可;

一、背景

远古时期,当时前后端还是不分离的,路由全部都是由服务端控制的,前端代码和服务端代码过度融合在一起。

客户端-->前端发起http请求-->服务端-->url路径去匹配不同的路由-->返回不同的数据。

这种方式的缺点和优点都非常明显:

优点:因为直接返回一个html,渲染了页面结构。SEO的效果非常好,首屏时间特别快;
在浏览器输入一个url开始到页面任意元素加载出来/渲染出来-->首屏时间;缺点:前端代码和服务端代码过度融合在一起,开发协同非常的乱。服务器压力大,因为把构建html的工作放在的服务端;

后来 …随之ajax的流行,异步数据请求可以在浏览器不刷新的情况下进行。

后来 …出现了更高级的体验 ——单页应用

-->HTML文件单页-->单个HTML文件

在单页应用中,不仅在页面中的交互是不刷新页面的,就连页面跳转也都是不刷新页面的。

单页应用的特点:

页面中的交互是不刷新的页面的,比如点击按钮,比如点击出现一个弹窗;多个页面间的交互,不需要刷新页面(a/b/ca-> b -> c);加载过的公共资源,无需再重复加载;

而支持起单页应用这种特性的,就是前端路由

二、前端路由特性

前端路由的需求是什么?

根据不同的url渲染不同内容;不刷新页面;

也就是可以在改变url的前提下,保证页面不刷新。

三、面试!!!

Hash路由和History路由的区别?

hash#history没有#hash#部分内容不会给服务端,主要一般是用于锚点,history的所有内容都会给服务端;hash路由是不支持SSR的,history路由是可以的;hash通过hashchange监听变化,history通过popstate监听变化;

四、Hash 原理及实现

1、特性

hash的出现满足了这个需求,他有以下几种特征:

url中带有一个#符号,但是#只是浏览器端/客户端的状态,不会传递给服务端;
客户端路由地址www.baidu.com/#/user-->通过http请求-->服务端接收到的www.baidu.com/客户端路由地址www.baidu.com/#/list/detail/1-->通过http请求-->服务端接收到的www.baidu.com/hash值的更改,不会导致页面的刷新;

不同url会渲染不同的页面;hash值的更改,会在浏览器的访问历史中添加一条记录,所以我们才可以通过浏览器的返回、前进按钮来控制hash的切换;hash值的更改,会触发hashchange事件;

2、如何更改 hash

我们同样有两种方式来控制hash的变化:

location.hash的方式:

html标签的方式:

3、手动实现一个基于 hash 的路由

./index.html

./index.css

./index.js

五、History 原理及实现

hash有个#符号,不美观,服务端无法接受到hash路径和参数。

历史的车轮无情撵过hash,到了HTML5时代,推出了History API

1、HTML5 History 常用的 API

其中最主要的两个APIpushStatereplaceState,这两个API都可以在不刷新页面的情况下,操作浏览器历史记录。

不同的是,pushState会增加历史记录,replaceState会直接替换当前历史记录。

2、pushState/replaceState 的参数

pushState:页面的浏览记录里添加一个历史记录;replaceState:替换当前历史记录;

他们的参数是⼀样的,三个参数分别是:

state:是一个对象,是一个与指定网址相关的对象,当popstate事件触发的时候,该对象会传入回调函数;title:新页面的标题,浏览器支持不一,建议直接使用nullurl:页面的新地址;

3、History 的特性

History API有以下几个特性:

没有#history.pushState()history.replaceState()不会触发popstate事件,这时我们需要手动触发页面渲染;可以使用history.popstate事件来监听url的变化;只有用户点击浏览器倒退按钮前进按钮,或者使用JavaScript调用backforwardgo方法时才会触发popstate

4、面试!!!

pushState时,会触发popstate吗?

pushState/replaceState并不会触发popstate事件,这时我们需要手动触发页面的重新渲染;

我们可以使用popstate来监听url的变化;

popstate到底什么时候才能触发:

点击浏览器后退按钮;点击浏览器前进按钮;js调用back方法;js调用forward方法;js调用go方法;

5、手动实现一个基于 History 的路由

./index.html
./index.css

./index.js

六、Vue-Router

1、router 使用

使用Vue.js,我们已经可以通过组合组件来组成应用程序,当你要把Vue Router添加进来,我们需要做的是,将组件(components)映射到路由(routes),然后告诉Vue Router在哪里渲染它们。

举个例子:


2、动态路由匹配

我们经常需要把某种模式匹配到的所有路由,全部映射到同个组件,比如用户信息组件,不同用户使用同一个组件。

可以通过$route.params.id或者参数。

3、响应路由参数的变化

复用组件时,想对路由参数的变化作出响应的话,可以使用watch或者beforeRouteUpdate

举个例子:

4、捕获所有路由或 404 Not found 路由

当时用通配符路由时,请确保路由的顺序是正确的,也就是说含有通配符的路由应该在最后

举个例子:

5、导航守卫

vue-router提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种方式植入路由导航过程中:

全局的全局前置守卫:router.beforeEach全局解析守卫:router.beforeResolve全局后置钩子:router.afterEach单个路由独享的路由独享守卫:beforeEnter组件级的beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave

6、完整的导航解析流程

导航被触发;在失活的组件里调用离开守卫(前一个组件的beforeRouteLeave);调用全局的beforeEach守卫;在重用的组件里调用beforeRouteUpdate守卫;在路由配置里调用beforeEnter;解析异步路由组件;在被激活的组件里调用beforeRouterEnter;调用全局的beforeResolve守卫;导航被确认;调用全局的afterEach钩子;触发DOM更新;用创建好的实例调用beforeRouterEnter守卫中传给next的回调函数;

举个例子:

next必须调用:

next():进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是confirmed(确认的)。next(false):中断当前的导航。如果浏览器的URL改变了(可能是用户手动或者浏览器后退按钮),那么URL地址会重置到from路由对应的地址。next("/")或者next({ path: "/" }):跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。可以向next传递任意位置对象,且允许设置诸如replace: truename: "home"之类的选项以及任何用在router-linkto proprouter.push中的选项。next(error):如果传入next的参数是一个Error实例,则导航会被终止且该错误会被传递给router.onError()注册过的回调。

7、导航守卫执行顺序(面试!!!)

【组件】前一个组件的beforeRouteLeave【全局】的router.beforeEach【组件】如果是路由参数变化,触发beforeRouteUpdate【配置文件】里,下一个的beforeEnter【组件】内部声明的beforeRouteEnter【全局】的router.afterEach

8、滚动行为(面试!!!)

vue-router里面,怎么记住前一个页面的滚动条的位置???

使用前端路由,当切换到新路由时,想要页面滚动到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。

Vue-router能做到,而且更好,它让你可以自定义路由切换时页面如何滚动。

【注意】:这个功能只在支持history.pushState的浏览器中可用。

scrollBehavior生效的条件:

浏览器支持history API;页面间的交互是通过goforwardback或者浏览器的前进/返回按钮

举个例子

9、路由懒加载

当打包构建应用时,JavaScript包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

举个例子:

给TA打赏
共{{data.count}}人
人已打赏
网站运维

JavaScript变量中var,let和const的区别(javascript let const var)

2022-10-11 21:56:34

网站运维

sql如何设置主键、如何删除主键约束(数据库删除主键约束)

2022-10-12 19:17:41

声明 本站上的部份代码及教程来源于互联网,仅供网友学习交流,若您喜欢本文可附上原文链接随意转载。无意侵害您的权益,请发送邮件至 [email protected] 或点击右侧 私信:林沐阳 反馈,我们将尽快处理。
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索