EggJs单页面应用的基本实现

说到SPA(single page web application)单页面应用,想必各位前端Coder都不会陌生,不论是目前主流的React、Vue还是Angular都能够看到SPA的影子,但是很多开发和对于这个概念还是处于一种一知半解的状态,今天我们一起来学习研究一下SPA的简单实现。

先上github项目地址: Egg.js

显示效果图

背景介绍

基础知识

相信用过VUE.js开发SPA项目的小伙伴一定对路由跳转不陌生。浏览器的URL地址栏中的会有一个“#”标识符,同时在路由跳转的时候 #(锚部分:以下统称为路由)会发生变化,在页面不刷新的情况下渲染当前路由对应模块的代码。

那么这是怎么实现的呢

当然了实现对的方法其实有很多种,甚至你都可以使用Ajax/Fetch去做请求然后动态的修改页面结构,但是这样无异于增加工作量,其实还有更好的方法,就是使用hash路由跟html5提供的historyapiAPI。今天我们先使用hash路由也就是#的方法来实现。

首先我们先看看location对象给我们提供了哪些属性:

显示效果图

location对象

可见在location提供的第一个属性hash就是我们需要的,那么实现的大致方案就清晰了。

实现方案

  • 获取location对象的hash属性并截取hash的路由跟可能存在的参数
  • 配置路由对应的代码
  • 根据路由加载不同的模块代码

获取location的hash并分离路由跟参数

通过使用String类型的split方法对hash进行字符串截取,从而分离路由跟可能存在的参数

block
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Util_QsHasUrl = (hash) => {
const [, l] = hash.split('/');
const [u, p] = l.split('?');
let t = {};
if (p) {
p.split('&').forEach(item => {
const p = item.split('=');
t[`${p[0]}`] = p[1]
})
}
return {
u: u,
p: t ||{}
}
}

配置路由对应的文件

配置路由对应的文件并且导出

block
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import Page1 from '../Pages/Page1/page1.js';
import Page2 from '../Pages/Page2/page2.js';
import Page3 from '../Pages/Page3/page3.js';
import Page4 from '../Pages/Page4/page4.js';

const routes=[{
routeName:'page1',
component:Page1
},
{
routeName:'page2',
component:Page2
},
{
routeName:'page3',
component:Page3
},
{
routeName:'page4',
component:Page4
}];

export default routes;

根据路由加载不同的模块代码

  • 此处的hashName对应代码一种返回值的u(urlHash)url获取的路由值

  • senData对应代码一种返回值的p(param) url截取的参数

block
1
2
3
4
5
6
7
8
9
10
11
12
13
14
checkPage = (hashName,senData) => {
let hasFoundRoute = false;
for (var i of (this.routeList)) {
if (i.routeName === hashName) {
hasFoundRoute = true;
console.log('find Module',i);
let renderModule= new i.component(senData);
this.targetRoot[0].innerHTML=renderModule.render();
}
}
if (!hasFoundRoute) {
this.targetRoot[0].innerHTML=NotFound();//预设的404模块
}
}

通过以上三部基本上就实现了单页面应用异步加载模块的功能

具体代码可以参看github地址,欢迎大家评论,点赞。