# 什么是SPA
包括像
vue
、react
等主流前端框架,目前都是采用单页面应用(single page application
)的形式构建一个web应用 单页面顾名思义就是页面开始就一个节点,后面所有的操作都是在这个节点上进行增删改查,动态实现页面的跳转,从而实现页面的切换(路由操作) 本质:根据地址栏变化(不重新想服务器发送请求), 去局部更新不同的页面内容, 完成前端业务场景切换
# 实现单页面功能
主要功能点 支持路由懒加载 支持重定向功能 本文只实现hash模式下的路由侦测
1.html部分:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 一堆 CSS 代码, 与简单实现时一样, 这里不做重复书写 */
</style>
</head>
<body>
<div class="box">
<div class="top"> 顶部通栏 </div>
<div class="bottom">
<div class="slide">
<a href="#/pageA">pageA</a>
<a href="#/pageB">pageB</a>
<a href="#/pageC">pageC</a>
<a href="#/pageD">pageD</a>
</div>
<div class="content router-view"></div>
</div>
</div>
<!-- 注意使用模块发的方式导入文件 -->
<script src="./index.js" type="module"></script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2.router.js:
功能点
1.路由懒加载 2.重定向
const router = [
{
name: "/pageA",
compoment: () => import("./components/templateA.js"),
},
{
name: "/pageB",
compoment: () => import("./components/templateB.js"),
},
{
name: "/pageC",
compoment: () => import("./components/templateC.js"),
},
{
name: "/pageD",
compoment: () => import("./components/templateD.js"),
},
{
// 如果当前的 路由是 /, 那么就重定向到 /pageA
name: "/",
redirect: "/pageA",
},
];
// 导出路由表
export default router;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
3.index.js:
主要实现hash模式
import router from "./router.js";
// 注册 hash 改变事件
window.onhashchange = hashChangeHandler;
hashChangeHandler();
function hashChangeHandler() {
const hash = window.location.hash.slice(1) || "/";
const info = router.find((t) => t.name === hash);
// 路由表中 重定向的优先级最高
if (info.redirect) return (window.location.hash = info.redirect);
// 调用 component 的到一个返回值, 如果是普通引入, 那么这里一定是 undefined, 我们直接 return 即可
const res = info.compoment();
if (res === undefined) return;
// 代码能运行到这里说明我们 调用 component 得到的是一个 promise 对象, 所以我们可以通过 then 方法以及他的参数去调用我们实际导出的内容
res.then((result) => result.default());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- SPA/components/templateA.js:
const temAHtml = `<div id="pageA">pageA_template</div>`;
const routerView = document.querySelector('.router-view')
function rander () {
routerView.innerHTML = temAHtml
}
export default rander
1
2
3
4
5
6
2
3
4
5
6
- SPA/components/templateB.js:
const temBHtml = `<div id="pageB">pageB_template</div>`;
const routerView = document.querySelector('.router-view')
function rander () {
routerView.innerHTML = temBHtml
}
export default rander
1
2
3
4
5
6
2
3
4
5
6
- SPA/components/templateC.js:
const temCHtml = `<div id="pageC">pageC_template</div>`;
const routerView = document.querySelector('.router-view')
function rander () {
routerView.innerHTML = temCHtml
}
export default rander
1
2
3
4
5
6
2
3
4
5
6
- SPA/components/templateD.js:
const temDHtml = `<div id="pageD">pageD_template</div>`;
const routerView = document.querySelector('.router-view')
function rander () {
routerView.innerHTML = temDHtml
}
export default rander
1
2
3
4
5
6
2
3
4
5
6
← vue@3.x vue-router原理 →