history路由
class HistoryRouter{
constructor(){
//用于存储不同path值对应的回调函数
this.routers = {};
this.listenPopState();
this.listenLink();
}
//监听popstate
listenPopState(){
window.addEventListener('popstate',(e)=>{
let state = e.state || {},
path = state.path || '';
this.dealPathHandler(path)
},false)
}
//全局监听A链接
listenLink(){
window.addEventListener('click',(e)=>{
let dom = e.target;
if(dom.tagName.toUpperCase() === 'A' && dom.getAttribute('href')){
e.preventDefault()
this.assign(dom.getAttribute('href'));
}
},false)
}
//用于首次进入页面时调用
load(){
let path = location.pathname;
this.dealPathHandler(path)
}
//用于注册每个视图
register(path,callback = function(){}){
this.routers[path] = callback;
}
//用于注册首页
registerIndex(callback = function(){}){
this.routers['/'] = callback;
}
//用于处理视图未找到的情况
registerNotFound(callback = function(){}){
this.routers['404'] = callback;
}
//用于处理异常情况
registerError(callback = function(){}){
this.routers['error'] = callback;
}
//跳转到path
assign(path){
history.pushState({path},null,path);
this.dealPathHandler(path)
}
//替换为path
replace(path){
history.replaceState({path},null,path);
this.dealPathHandler(path)
}
//通用处理 path 调用回调函数
dealPathHandler(path){
let handler;
//没有对应path
if(!this.routers.hasOwnProperty(path)){
handler = this.routers['404'] || function(){};
}
//有对应path
else{
handler = this.routers[path];
}
try{
handler.call(this)
}catch(e){
console.error(e);
(this.routers['error'] || function(){}).call(this,e);
}
}
}
1.创建一个路由对象, 实现 register 方法用于注册每个 location.pathname 值对应的回调函数
2.当 location.pathname === '/' 时,认为是首页,所以实现 registerIndex 方法用于注册首页时的回调函数
3.解决 location.path 没有对应的匹配,增加方法 registerNotFound 用于注册默认回调函数
4.解决注册的回到函数执行时出现异常,增加方法 registerError 用于处理异常情况
5.定义 assign 方法,用于通过 JS 触发 history.pushState 函数
6.定义 replace 方法,用于通过 JS 触发 history.replaceState 函数
7.监听 popstate 用于处理前进后退时调用对应的回调函数
8.全局阻止A链接的默认事件,获取A链接的href属性,并调用 history.pushState 方法
9.定义 load 方法,用于首次进入页面时 根据 location.pathname 调用对应的回调函数
//html
<body>
<div id="nav">
<a href="/page1">page1</a>
<a href="/page2">page2</a>
<a href="/page3">page3</a>
<a href="/page4">page4</a>
<a href="/page5">page5</a>
<button id="btn">page2</button>
</div>
<div id="container"> </div>
</body>
//js测试
let router = new HistoryRouter();
let container = document.getElementById('container'); //注册首页回调函数
router.registerIndex(() => container.innerHTML = '我是首页'); //注册其他视图回到函数
router.register('/page1', () => container.innerHTML = '我是page1');
router.register('/page2', () => container.innerHTML = '我是page2');
router.register('/page3', () => container.innerHTML = '我是page3');
router.register('/page4', () => {
throw new Error('抛出一个异常')
}); document.getElementById('btn').onclick = () => router.assign('/page2') //注册未找到对应path值时的回调
router.registerNotFound(() => container.innerHTML = '页面未找到');
//注册出现异常时的回调
router.registerError((e) => container.innerHTML = '页面异常,错误消息:<br>' + e.message);
//加载页面
router.load();
history路由的更多相关文章
- Router和History (路由控制)-backbone
Router和History (路由控制) Backbone.Router担任了一部分Controller(控制器)的工作,它一般运行在单页应用中,能将特定的URL或锚点规则绑定到一个指定的方法(后文 ...
- 告别 hash 路由,迎接 history 路由
博客地址:https://ainyi.com/69 三月来了,春天还会远吗.. 在这里,隆重宣布本博客告别 Vue 传统的 hash 路由,迎接好看而优雅的 history 路由~~ 映照官方说法 v ...
- 单页面应用的History路由模式express后端中间件配合
这篇文章主要分享一下通过HTML5的history API的时候,使用NodeJS后端应该如何配置,来避免产生404的问题,这里是使用的express的框架,主要是通过connect-history- ...
- history路由模式下的nginx配置
路由模式 众所周知,浏览器下的单页面应用的路由模式有下面两种: hash 模式和 history 模式.hash 模式通用性好,而且不依赖服务器的配置,省心省力,但是缺点是不够优雅.相比于 hash ...
- vue cli3项目发布在apache www/vue目录下并配置history路由
注意:vue项目打包后默认是指向服务器的根路径(比如apache默认www目录是根路径,当然也可以修改),这种情况不需要做路径的配置,只需要做history配置,如果不是发布到根路径而是www/vue ...
- vue采用history路由的服务器部署问题
发现部署问题 在部署的时候发现打开的页面是空白 之前部署原理 之前的页面都是作为静态文件形式打包上传到服务器上 http://www.xiedashuaige.cn/bolg2.0/#/home 就和 ...
- nginx 一个端口布署多个单页应用(history路由模式)。
目前web开发 使用一般前后端分离技术,并且前端负责路由.为了美观,会采用前端会采用h5 history 模式的路由.但刷新页面时,前端真的会按照假路由去后端寻找文件.此时,后端必须返回index(i ...
- nginx history路由模式时,页面返回404重定向index.html
1.路由默认是带#的,有时我们感觉不美观,就使其变为history模式,也就没有#字符 2.# 如果找不到当前页面(404),就返回index.html,重新分配路由 location ^~/prod ...
- hash和history路由的区别
在了解路由模式前,我们先看下 什么是单页面应用,vue-router 的实现原理是怎样的,这样更容易理解路由. SPA与前端路由 SPA(单页面应用,全程为:Single-page Web appl ...
随机推荐
- 使用QtCreator运行Gstreamer程序
1.创建一个简单的Plain C Application 2.Build System选择qmake 3.Kit Selection默认Desktop Qt x.xx.x GCC 64bit 4..p ...
- poj 3281Dining(网络流 拆点)
题目链接:http://poj.org/problem?id=3281 题目大意:John养了N只奶牛,他为奶牛准备了F个食物和D个饮料,但是每只奶牛只对其中的一些饮料和食物感兴趣,现在请制定一些方案 ...
- 【做题笔记】P1042 乒乓球
坑 #1:输入有若干行,但处理的时候要看成一个整体的信息.比如说第一行最后一局比分是 2:1 ,这时不算比完,这个比分要继承到第二行的信息中继续处理. 坑 #2:一局结束,当且仅当其中一方比分大于等于 ...
- IntelliJ IDEA 2017.3尚硅谷-----卸载
直接在用户目录下搜索,卸载的干净就要删除 删除这两个目录,重启idea可以还原配置. editplus删除后重启也是这个效果
- 高斯消元-bzoj1013-球形空间产生器
This article is made by Jason-Cow.Welcome to reprint.But please post the writer's address. http://ww ...
- 【PAT甲级】1104 Sum of Number Segments (20 分)
题意:输入一个正整数N(<=1e5),接着输入N个小于等于1.0的正数,输出N个数中所有序列的和. AAAAAccepted code: #define HAVE_STRUCT_TIMESPEC ...
- Kali国内源更新sources.list
Kali国内源更新sources.list 更新源,个人推荐中科大leafpad /etc/apt/sources.list #中科大 deb http://mirrors.ustc.ed ...
- etc/hosts文件详解
Linux 修改 etc/hosts文件 hosts文件 hosts —— the static table lookup for host name(主机名查询静态表). hosts文件是Linux ...
- JEECG右上角用户信息完整显示
最近在使用JEECG框架,发现一个问题,就是右上角的用户信息显示不完整(如下图所示),现在想把完整信息显示出来 首先想到的是overflow样式问题,想通过修改样式显示完整信息,通过各种删除修改也没有 ...
- django+vue 基础框架 :vue
<template> <div> <p>用户名:<input type="text" v-model="name"&g ...