不用vue实现spa
使用原生 JavaScript 实现 SPA
通过监听 URL 变化动态加载内容,无需框架即可实现单页应用(SPA)的核心功能。
路由管理
class Router {
constructor(routes) {
this.routes = routes;
window.addEventListener('popstate', () => this.handleRouteChange());
}
handleRouteChange() {
const path = window.location.pathname;
const route = this.routes.find(r => r.path === path);
if (route) {
document.getElementById('app').innerHTML = route.component;
}
}
navigate(path) {
window.history.pushState({}, '', path);
this.handleRouteChange();
}
}
页面切换
const routes = [
{ path: '/', component: '<h1>Home</h1>' },
{ path: '/about', component: '<h1>About</h1>' }
];
const router = new Router(routes);
document.addEventListener('DOMContentLoaded', () => router.handleRouteChange());
使用 History API 控制导航
通过 history.pushState 实现无刷新页面跳转,配合事件监听完成完整路由系统。
状态管理

window.addEventListener('popstate', () => {
const currentPath = window.location.pathname;
updateView(currentPath);
});
function updateView(path) {
const viewContainer = document.getElementById('app');
viewContainer.innerHTML = getViewContent(path);
}
动态内容加载方案
采用 AJAX 技术按需加载页面片段,提升应用性能。
XMLHttpRequest 实现
function loadView(url, targetId) {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = () => {
document.getElementById(targetId).innerHTML = xhr.responseText;
};
xhr.send();
}
Fetch API 替代方案

async function fetchView(url) {
const response = await fetch(url);
const html = await response.text();
document.getElementById('app').innerHTML = html;
}
模块化开发方案
通过 ES6 模块系统组织代码结构,保持项目可维护性。
模块定义
// views/home.js
export const render = () => '<h1>Home Page</h1>';
// main.js
import { render as homeRender } from './views/home.js';
document.getElementById('app').innerHTML = homeRender();
性能优化技巧
预加载策略
<link rel="preload" href="about.html" as="document">
缓存管理
const viewCache = {};
async function getView(url) {
if (!viewCache[url]) {
viewCache[url] = await fetch(url).then(r => r.text());
}
return viewCache[url];
}
完整实现示例
class SPA {
constructor(config) {
this.routes = config.routes;
this.initRouter();
this.bindLinks();
}
initRouter() {
window.addEventListener('popstate', () => this.renderView());
document.addEventListener('DOMContentLoaded', () => this.renderView());
}
bindLinks() {
document.body.addEventListener('click', e => {
if (e.target.matches('[data-link]')) {
e.preventDefault();
this.navigate(e.target.href);
}
});
}
navigate(url) {
window.history.pushState({}, '', url);
this.renderView();
}
renderView() {
const path = window.location.pathname;
const route = this.routes.find(r => r.path === path);
document.getElementById('app').innerHTML = route
? route.component
: '<h1>404 Not Found</h1>';
}
}
new SPA({
routes: [
{ path: '/', component: '<h1>Home</h1>' },
{ path: '/contact', component: '<h1>Contact</h1>' }
]
});






