vue history模式原理

28 阅读1分钟
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>原生JS实现Vue History路由</title>
</head>
<body>
  <div id="app">
    <nav>
      <a href="/">首页</a>
      <a href="/about">关于</a>
      <a href="/contact">联系我们</a>
    </nav>
    
    <div id="router-view"></div>
  </div>

  <script>
    // 1. 路由配置
    const routes = {
      '/': '<h1>首页内容</h1>',
      '/about': '<h1>关于我们</h1><p>这是关于页面</p>',
      '/contact': '<h1>联系我们</h1><p>电话:123456789</p>',
      '*': '<h1>404 页面不存在</h1>' // 匹配不到时的默认页面
    };

    // 2. 路由实例
    const router = {
      // 当前路径
      currentPath: window.location.pathname,
      
      // 路由初始化
      init() {
        console.log(123)
        // 初始渲染
        this.render();
        
        // 监听 popstate 事件(后退/前进按钮)
        window.addEventListener('popstate', () => {
          this.currentPath = window.location.pathname;
          this.render();
        });
        
        // 拦截所有链接点击,使用 pushState 代替默认跳转
        document.querySelectorAll('a').forEach(link => {
          link.addEventListener('click', (e) => {
            e.preventDefault();
            const path = link.getAttribute('href');
            this.navigate(path);
          });
        });
      },
      
      // 导航到指定路径
      navigate(path) {
        // 更新浏览器历史记录
        history.pushState(null, null, path);
        // 更新当前路径
        this.currentPath = path;
        // 重新渲染
        this.render();
      },
      
      // 渲染当前路径对应的组件
      render() {
        const routerView = document.getElementById('router-view');
        // 根据当前路径查找对应的内容,找不到则使用通配符 *
        const content = routes[this.currentPath] || routes['*'];
        routerView.innerHTML = content;
      }
    };

    // 3. 初始化路由
    router.init();
  </script>
</body>
</html>