vue-router两种路由模式

前端路由

路由这个概念最先是后端出现的,简单来说就是用来跟后端服务器进行交互的一种方式,通过不同的路径,来请求不同的资源,请求不同的页面是路由的其中一种功能。

随着 ajax 的流行,异步数据请求交互运行在不刷新浏览器的情况下进行。而异步交互体验的更高级版本就是 SPA —— 单页应用。单页应用不仅仅是在页面交互是无刷新的,连页面跳转都是无刷新的,为了实现单页应用,所以就有了前端路由。

类似于服务端路由,前端路由实现起来其实也很简单,就是匹配不同的 url 路径,进行解析,然后动态的渲染出区域 html 内容。但是这样存在一个问题,就是 url 每次变化的时候,都会造成页面的刷新。那解决问题的思路便是在改变 url 的情况下,保证页面的不刷新。

hash 模式

在 2014 年之前,大家是通过 hash 来实现路由,url hash 就是类似于:

http://www.xxx.com/#/login

#后面 hash 值的变化,并不会导致浏览器向服务器发出请求,浏览器不发出请求,也就不会刷新页面。

另外每次 hash 值的变化,还会触发 hashchange 这个事件,通过这个事件我们就可以知道 hash 值发生了哪些变化。然后我们便可以监听 hashchange 来实现更新页面部分内容的操作。

function matchAndUpdate () {
   // todo 匹配 hash 做 dom 更新操作
}

window.addEventListener('hashchange', matchAndUpdate)

hash 模式背后的原理是 onhashchange 事件,可以在 window 对象上监听这个事件:

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

HashHistory有两个方法:HashHistory.push()将新路由添加到浏览器访问历史的栈顶 和 HashHistory.replace()替换掉当前栈顶的路由。

在这里插入图片描述

在这里插入图片描述
因为hash发生变化的url都会被浏览器记录(历史访问栈)下来,从而你会发现浏览器的前进后退都可以用了。这样一来,尽管浏览器没有请求服务器,但是页面状态和url一一关联起来。

history 模式

14年后,因为HTML5标准发布。多了两个 API,pushStatereplaceState,通过这两个 API:

  • 可以改变 url 地址且不会发送请求
  • 不仅可以读取历史记录栈,还可以对浏览器历史记录栈进行修改

同时还有 popstate 事件:

  • 当浏览器跳转到新的状态时,将触发 popState 事件
function matchAndUpdate () {
   // todo 匹配路径 做 dom 更新操作
}

window.addEventListener('popstate', matchAndUpdate)

通过这些就能用另一种方式来实现前端路由了,但原理都是跟 hash 实现相同的。

如果要考虑url规范,就要使用history模式,例如在app中需要将页面分享到第三方app,有的app里面url是不允许带有#号的,所以要将#号去除那么就要使用history模式。

修改历史状态

包括了pushStatereplaceState两个方法,这两个方法接收三个参数:stateObjtitleurl

window.history.pushState(stateObject, title, URL)
window.history.replaceState(stateObject, title, URL)

切换历史状态

包括backforwardgo三个方法,对应浏览器的前进forward,后退back,跳转go操作。

history.go(-2); // 后退两次
history.go(2); // 前进两次
history.back(); // 后退
hsitory.forward(); // 前进

history模式怕啥

不怕前进,不怕后退,就怕刷新。因为没有 # 号,所以当用户刷新页面之类的操作时,浏览器还是会给服务器发送请求。例如请求的路径是/user/id,这部分是会传到服务器的,如果服务器中没有相应的响应或者资源,会分分钟刷出一个404来。

为了避免出现这种情况,所以这个实现需要服务器的支持,需要把所有路由都重定向到根页面。

const Koa = require('koa')
const Router = require('koa-router');
const static = require('koa-static')
const fs = require('fs');
const app = new Koa();
const router = new Router();

let str;
fs.readFile('../dist/index.html', "utf-8", (err, data) => {
    if (err) {
        ctx.body = "error found"
    }
    str = data.toString();
})

// 解决vue 路由在 history刷新 404情况
router.get('*', async(ctx, next) => {
    if (ctx.url !== "/index.html") {
        console.log("在这里返回")
        ctx.body = str;
    }
})

app.use(static("../dist/"));
app.use(router.routes()) //启动路由
app.use(router.allowedMethods());


app.listen(8989, () => {
    console.log("监听服务器地址:127.0.0.1:8989");
})

参考:
前端路由简介以及vue-router实现原理
vue-router两种模式的区别
vue路由的两种模式,hash与history的区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值