阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Vue中vue-router实现原理详解

636次阅读
没有评论

共计 4905 个字符,预计需要花费 13 分钟才能阅读完成。

Vue 中 vue-router 实现原理详解

vue-router 概念

vue-router 是 Vue 官方推出的路由管理器,它和 vue.js 是深度集成的,主要用于管理 URL,实现 URL 和组件的对应,以及通过 URL 进行组件之间的切换,通过改变 URL,在不重新请求页面的情况下,更新页面视图,从而使构建单页面应用变得更加简单。

vue-router 是基于路由和组件的

  • 路由用户设定访问路径的,将路径和组件映射起来;

  • 在 vue-router 的单页面应用中,页面的路径的改变就是组件的切换。

vue-router 模式

更新视图但不重新请求页面,是前端路由原理的核心之一,目前在浏览器环境中这一功能的实现主要有 2 种方式:

  1. Hash — 默认值,利用 URL 中的hash("#")

  2. history — 利用 URL 中的路径(/home)。

设置路由模式

const router=new VueRouter({
mode:'history',
routes:[...]
})

mode 区别

mode:“hash” 多了 “#”

http://localhost:8080/#/login

mode:“history”

http://localhost:8080/home

HashHistory

hash("#")的作用是加载 URL 中指示网页中的位置。#号后面的 hash 值,可通过 window.location.hash 获取

特点

  • hash 不会被包括在 http 请求中,对服务器端完全无用,因此,改变 hash 不会重新加载页面。

  • 可以为 hash 的改变添加监听事件:window.addEventListener("hashchange",funcRef,false)

  • 每一次改变hash(window.localtion.hash),都会在浏览器访问历史中增加一个记录。

  • 利用 hash 的以上特点,就可以来实现前端路由 “ 更新视图但不重新请求页面 ” 的功能了。

HashHistory 拥有两个方法:HashHistory.push()HashHistory.replace()

HashHistory.push()

HashHistory.push() 将新路由添加到浏览器访问历史的栈顶

Vue 中 vue-router 实现原理详解

从设置路由改变到视图更新的流程:

$router.push() --> HashHistory.push() -->History.transitionTo() --> History.updateRoute() --> {app._route = route} --> vm.render()

解释

$router.push() // 调用方法
HashHistory.push()// 根据 hash 模式调用, 设置 hash 并添加到浏览器历史记录(添加到栈顶)(window.location.hash= XXX)
History.transitionTo() // 监测更新,更新则调用 History.updateRoute()
History.updateRoute() // 更新路由
{app._route= route} // 替换当前 app 路由
vm.render() // 更新视图

HashHistory.replace()

replace()方法与 push() 方法不同之处在于,它并不是将新路由添加到浏览器访问历史的栈顶,而是替换掉当前的路由。

HTML5History

早期 History 通过 back()forward()go() 等方法,我们可以读取浏览器历史记录栈的信息。从 HTML5 开始 History 提供了 2 个新的方法:pushState()replaceState(),使得我们可以对浏览器历史记录栈进行修改:

window.history.pushState(data, title, targetURL);
  • @状态对象:传给目标路由的信息, 可为空;

  • @页面标题:目前所有浏览器都不支持, 填空字符串即可;

  • @可选 url:目标 url,不会检查 url 是否存在,且不能跨域。如不传该项, 即给当前 url 添加 data。

window.history.replaceState(data, title, targetURL);
  • @类似于 pushState, 但是会直接替换掉当前 url, 而不会在 history 中留下记录。

假定当前网址是 example.com/1.html,使用 pushState() 方法在浏览记录(History 对象)中添加一个新记录。

var stateObj = {foo: 'bar' };
history.pushState(stateObj, 'page 2', '2.html');

添加新记录后,浏览器地址栏立刻显示example.com/2.html,但并不会跳转到 2.html,甚至也不会检查 2.html 是否存在,它只是成为浏览历史中的最新记录。

这 2 个方法有个共同的特点:当调用他们修改浏览器历史栈后,虽然当前 url 改变了,但浏览器不会立即发送请求该 url,这就为单页应用前端路由,更新视图但不重新请求页面提供了基础。

更多操作:

history.pushState({page: 1}, 'title 1', '?page=1')
// URL 显示为 http://example.com/example.html?page=1

history.pushState({page: 2}, 'title 2', '?page=2');
// URL 显示为 http://example.com/example.html?page=2

history.replaceState({page: 3}, 'title 3', '?page=3');
// URL 显示为 http://example.com/example.html?page=3

history.back()
// URL 显示为 http://example.com/example.html?page=1

history.back()
// URL 显示为 http://example.com/example.html

history.go(2)
// URL 显示为 http://example.com/example.html?page=3

监听地址变化

在 HTML5History 的构造函数中监听popState(window.onpopstate)

popstate 事件会在点击后退、前进按钮 (或调用history.back()history.forward()history.go() 方法)时触发。前提是不能真的发生了页面跳转, 而是在由 history.pushState() 或者 history.replaceState() 形成的历史节点中前进后退

注意: 用 history.pushState() 或者 history.replaceState() 不会触发 popstate 事件。

window.onpopstate = function(event) {
console.log(event.state);
console.log(window.history.state;);
};

以上两种方式皆可获取之前在 pushState 和 replaceState 中传入的 data

注意,页面第一次加载的时候,浏览器不会触发 popstate 事件。

两种模式区别

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

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

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

  • history 模式则会将 URL 修改得就和正常请求后端的 URL 一样, 如后端没有配置对应 /user/id 的路由处理,则会返回 404 错误

辅助学习代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>pushState</title>
    <style type="text/css">
    .hidden {
        display: none;
    }
    </style>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head>

<body>
    <section id="step1" class="step-contain" step="1">
        <p>第 1 步</p>
        <button class="step-btn" step="1">下一步</button>
    </section>
    <section id="step2" class="step-contain hidden" step="2">
        <p>第 2 步</p>
        <button class="step-btn" step="2">下一步</button>
    </section>
    <section id="step3" class="step-contain hidden" step="3">
        <p>第 3 步</p>
    </section>
    <script type="text/javascript">
    $(function() {
        stepProgress();

        function stepProgress() {
            var options = {
                curStep: 1,
                nextStep: null
            }
            var defaultState={
                "step": options.curStep,
                 "url": "#step=" + options.curStep
            }
            window.history.pushState(defaultState, "", defaultState.url);
            $(".step-btn").on("click", function() {
                var step = parseInt($(this).attr("step"));
                options.nextStep = step + 1;
                var state = {
                    "step": options.nextStep,
                    "url": "#step=" + options.nextStep
                }
                window.history.pushState(state, "", state.url);
                console.log(state.step)
                swapStaus(options.nextStep);
            });

            function swapStaus(step) {
                $(".step-contain").each(function() {
                    var tmpStep = $(this).attr("step");
                    if (parseInt(tmpStep) == step) {
                        $("#step" + tmpStep).removeClass("hidden");
                    } else {
                        $("#step" + tmpStep).addClass("hidden");
                    }
                });
                options.curStep = step;
            }

            $(window).on("popstate",function(){
                var currentState = history.state;
                goStep=currentState.step?currentState.step:1;
                swapStaus(goStep)
            })
        }

    })
    </script>
</body>

</html>

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-07-03发表,共计4905字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19351
评论数
4
阅读量
7995738
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
150元打造低成本NAS小钢炮,捡一块3865U工控板

150元打造低成本NAS小钢炮,捡一块3865U工控板

150 元打造低成本 NAS 小钢炮,捡一块 3865U 工控板 一块二手的熊猫 B3 工控板 3865U,搭...
还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手! 前言 对于个人开发者、建站新手或是想搭建测试站点的从业者...
终于收到了以女儿为原型打印的3D玩偶了

终于收到了以女儿为原型打印的3D玩偶了

终于收到了以女儿为原型打印的 3D 玩偶了 前些日子参加某网站活动,获得一次实物 3D 打印的机会,于是从众多...
Prometheus:监控系统的部署与指标收集

Prometheus:监控系统的部署与指标收集

Prometheus:监控系统的部署与指标收集 在云原生体系中,Prometheus 已成为最主流的监控与报警...
12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换,告别多工具切换

12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换,告别多工具切换

12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
星哥带你玩飞牛NAS硬件03:五盘位+N5105+双网口的成品NAS值得入手吗

星哥带你玩飞牛NAS硬件03:五盘位+N5105+双网口的成品NAS值得入手吗

星哥带你玩飞牛 NAS 硬件 03:五盘位 +N5105+ 双网口的成品 NAS 值得入手吗 前言 大家好,我...
免费无广告!这款跨平台AI RSS阅读器,拯救你的信息焦虑

免费无广告!这款跨平台AI RSS阅读器,拯救你的信息焦虑

  免费无广告!这款跨平台 AI RSS 阅读器,拯救你的信息焦虑 在算法推荐主导信息流的时代,我们...
支付宝、淘宝、闲鱼又双叕崩了,Cloudflare也瘫了连监控都挂,根因藏在哪?

支付宝、淘宝、闲鱼又双叕崩了,Cloudflare也瘫了连监控都挂,根因藏在哪?

支付宝、淘宝、闲鱼又双叕崩了,Cloudflare 也瘫了连监控都挂,根因藏在哪? 最近两天的互联网堪称“故障...
星哥带你玩飞牛NAS-14:解锁公网自由!Lucky功能工具安装使用保姆级教程

星哥带你玩飞牛NAS-14:解锁公网自由!Lucky功能工具安装使用保姆级教程

星哥带你玩飞牛 NAS-14:解锁公网自由!Lucky 功能工具安装使用保姆级教程 作为 NAS 玩家,咱们最...
仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

还在忍受动辄数百兆的“全家桶”监控软件?后台偷占资源、界面杂乱冗余,想查个 CPU 温度都要层层点选? 今天给...