前端路由

93 阅读2分钟

什么是前端路由?

  • 前端路由(Frontend Routing)是指在Web应用程序中,通过JavaScript来管理和控制用户在浏览器中访问不同页面的机制。
  • 前端路由允许开发人员在单页应用(Single Page Application,SPA)或现代Web应用中创建多个虚拟页面,而无需每次加载新页面时都向服务器发出请求
  • 前端路由的主要目的是改善用户体验,使Web应用看起来更像传统的多页应用程序,而不是每次页面切换都需要重新加载整个页面。它通过在浏览器的地址栏中监听URL的变化,根据URL的不同加载不同的视图。

Vue Router 不同的历史模式

1. Hash 模式

1.1 vue中使用

hash 模式是用 createWebHashHistory() 创建的:

import { createRouter, createWebHashHistory } from 'vue-router'

const router = createRouter({
  history: createWebHashHistory(),
  routes: [
    //...
  ],
})

它在内部传递的实际 URL 之前使用了一个哈希字符(#)。由于这部分 URL 从未被发送到服务器,所以它不需要在服务器层面上进行任何特殊处理。不过,它在 SEO 中确实有不好的影响

1.2 原生js实现前端路由

<!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>
    <div>
        <a href="#/home">home</a>
        <a href="#/about">about</a>
        <div class="content">Default</div>
    </div>
    <script>
        const contentEl = document.querySelector('.content')
        window.addEventListener('hashchange', (e) => {
            console.log(e);
            console.log(window.location.hash);
            switch (window.location.hash) {
                case '#/home':
                    contentEl.innerHTML = 'Home'
                    break
                case '#/about':
                    contentEl.innerHTML = 'About'
                    break
                default:
                    contentEl.innerHTML = 'Default'
            }
        })
    </script>
</body>

</html>

2. History 模式

2.1 vue中使用

History 模式是用 createWebHistory() 创建的:

import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(),
  routes: [
    //...
  ],
})
  • 使用这种历史模式时,URL 会看起来很 "正常".
  • 由于我们的应用是一个单页的客户端应用,如果没有适当的服务器配置,用户在浏览器中直接访问 https://example.com/user/id,就会得到一个 404 错误。
  • 要解决这个问题,需要在你的服务器上添加一个简单的回退路由。如果 URL 不匹配任何静态资源,它应提供与你的应用程序中的 index.html 相同的页面。
nginx服务器配置
location / {
  try_files $uri $uri/ /index.html;
}

2.2 原生js实现前端路由

<!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>
    <div>
        <a href="/home">home</a>
        <a href="/about">about</a>
        <div class="content">Default</div>
    </div>
    <script>
        const changeContent = () => {
            switch (location.pathname) {
                case "/home":
                    contentEl.innerHTML = 'Home'
                    break
                case "/about":
                    contentEl.innerHTML = 'About'
                    break
                default:
                    contentEl.innerHTML = 'Default'
            }
        }
        const contentEl = document.querySelector('.content')
        const aEls = document.getElementsByTagName('a')
        console.log(aEls);
        for (const aEl of aEls) {
            aEl.addEventListener('click', e => {
                console.log(e);
                e.preventDefault()
                const href = aEl.getAttribute('href')
                console.log(href);
                // history.pushState({}, '', href)
                history.replaceState({}, '', href)
                changeContent()
            })
        }

        window.addEventListener('popstate', (e) => {
            console.log('popstate', e);
            changeContent()
        })
    </script>
</body>

</html>

参考文章1

参考文章2