赞
踩
MPA(Mutil Page Application)表示多页应用,整个应用有多个HTML页面。用户在多个HTML页面之间进行跳转的时候,要频繁的刷新页面,造成对用户的体验不好。
例子:
在点击a链接跳转到对应的页面时,注意浏览器的地址栏发生变化,且页面重新刷新,页面刷新又代表着重新请求了资源(F12查看网络请求)。即每一次跳转都要重新发送一次HTTP请求。
//a.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <h1>MPA</h1> <div> <a href="./a.html">a页面</a> <a href="./b.html">b页面</a> </div> <div>AAA</div> </body> </html>
//b.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <h1>MPA</h1> <div> <a href="./a.html">a页面</a> <a href="./b.html">b页面</a> <a href="www.baidu.com" onclick="return false">baidu</a> </div> <div>BBB</div> </body> </html>
SPA(Single Page Application)表示单页应用,即整个应用中只有一个HTML文件(单页面,多组件)。单页面应用不会有上述反复发送HTTP请求的缺点。
因为要将浏览器路径与组件进行匹配,当路径变化时,渲染相应的组件,所以需要前端路由。
参考链接
参考链接
路由的实现依赖于BOM的History对象,可以通过操作这个对象实现路径的跳转。还能监听多个路径的跳转过程。
例子:
History对象维护了一个栈,栈里面存放的就是浏览器的各个历史路径。
(1)使用live server打开HTML文件,此时浏览器显示的路径可能是http://127.0.0.1:5500/history.html,这个路径此时在栈底;
(2)假设你点击了a链接,则此时浏览器的路径就变成了http://127.0.0.1:5500/test1,此时的栈变成了下图这样。此时你点击回退,则会退到http://127.0.0.1:5500/history.html;点击前进则恢复原样。
(3)如果此时点击replace,则这个push的路径会将栈顶的元素替换掉。如下图:
如果此时再点击后退,则不是回到路径http://127.0.0.1:5500/test1,而是回到此时栈顶的路径http://127.0.0.1:5500/test3。
注意:整个过程页面都不会进行刷新。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <script src="https://cdn.bootcdn.net/ajax/libs/history/4.7.2/history.js"></script> </head> <body> <a href="/test1" onclick="return push('/test1')">push test1</a> <button onclick="push('/test2')">push test2</button> <button onclick="replace('/test3')">replace</button> <button onclick="forward()">前进</button> <button onclick="back()">后退</button> <script type="text/javascript"> let history = History.createBrowserHistory(); //let history = History.createHashHistory(); //hash路由类似锚链接,路径上会加上/#/ history.listen((location) => { console.log("监听到了路径变化:", location); }); function push(path) { history.push(path); //这里返回false是为了阻止a链接的默认事件 //不让其进行页面的跳转,只将浏览器路径进行变化 return false; } function replace(path) { history.replace(path); } function back() { history.go(-1); // history.goBack(); } function forward() { history.go(1); // history.goForward(); } </script> </body> </html>
既然能够监测到路径的变化,那么当路径变化时,我们渲染对应的组件就OK了。
使用vite搭建一个react + js 的项目
解读:
在App根组件刚挂载的时候,就去监听hashchange事件。当事件被触发后,就将新的hash路径赋值给状态current,再根据current的值渲染不同的组件。
src/App.jsx import { useEffect } from "react"; import { useState } from "react"; import { Link } from "react-router-dom"; import A from "./A"; import B from "./B"; function App() { const [current, setCurrent] = useState(""); const hashChange = () => { console.log(window.location.hash); setCurrent(window.location.hash.slice(1)); }; useEffect(() => { hashChange(); window.addEventListener("hashchange", hashChange); return () => { window.removeEventListener("hashchange", hashChange); }; }, []); return ( <> <div> <a href="#/a">A组件</a> </div> <div> <a href="#/b">B组件</a> </div> <div> {current === "/a" && <A></A>} {current === "/b" && <B></B>} </div> </> ); } export default App;
src/A.jsx
export default function A() {
return <div>AAA</div>;
}
src/B.jsx
export default function B() {
return <div>BBB</div>;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。