「掌握前端路由,打造单页应用的界面交互」

123 阅读3分钟

1. hash模式

在hash模式中,一般会把路径信息放在URL的hash部分,例如:

http://www.example.com/#/home
http://www.example.com/#/about

hash 指的是 url 中 # 后面的部分,例如:http://example.com/#/home。hash 路由的原理就是根据 url 中的 hash 部分,通过 JavaScript 监听 hashchange 事件,以此来控制视图的更新,实现单页应用的效果。在页面中设置一个空的 div 元素作为“视图容器”,然后利用 Hashchange 事件来监听地址变化,并检查hash,匹配相应的组件进行更新改变视图。

// HTML
<div id="view-container"></div>

// JS
function loadRoute() {
  let hash = window.location.hash;
  let view = document.getElementById("view-container");
  switch (hash) {
    case "":
    case "#/home":
      view.innerHTML = "Welcome to home page";
      break;
    case "#/about":
      view.innerHTML = "This is about page";
      break;
    default:
      view.innerHTML = "404 Page Not Found";
  }
}

window.addEventListener("hashchange", loadRoute);

举个例子,假设我们有一个简单的Vue单页应用程序:

<!DOCTYPE html>
<html>
<head>
  <title>A Simple Vue.js App</title>
  <!-- 引入 Vue.js 和 Vue Router -->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="https://unpkg.com/vue-router@4.0.11/dist/vue-router.min.js"></script>
</head>
<body>
  <div id="app">
    <router-link to="/home">首页</router-link>
    <router-link to="/about">关于我们</router-link>

    <router-view></router-view>
  </div>

  <script>
    // 创建路由实例
    const router = VueRouter.createRouter({
      history: VueRouter.createWebHashHistory(), // 使用 hash 模式
      routes: [
        { path: '/home', component: Home },
        { path: '/about', component: About }
      ]
    })

    // 创建 Vue 实例
    const app = Vue.createApp({})
    app.use(router)

    // 定义组件并注册到 Vue 实例上
    const Home = { template: '<div>这里是首页</div>' }
    const About = { template: '<div>这里是关于我们</div>' }

    app.mount('#app')
  </script>
</body>
</html>

在这个例子中,我们使用Vue Router来实现前端路由,并使用 VueRouter.createWebHashHistory() 创建一个“路由历史”对象,以支持hash模式。当用户点击首页或关于我们时,页面的URL 的hash部分会发生变化,例如从 http://www.example.com/#/home变为http://www.example.com/#/about,但页面不会重新加载。相反,根据路由规则,对应的组件(Home或About)将被渲染(html5历史API也可以用类似方式监听popstate事件做路由切换)。

2. history模式

History API 是 HTML5 中新增的一个特性,主要用于浏览器的前端路由实现。相较于传统的后端路由,在前端路由中,页面刷新不会重新加载整个页面,而是只会局部刷新,用户体验更加流畅。

基于 History API 的路由原理很简单,它通过监听浏览器地址栏的变化来实现路由跳转。当用户访问页面时,第一次通过 JS 代码使用 pushState 方法将当前页面的 URL 添加到浏览器历史记录中,并且渲染对应的页面内容,而后用户在界面点击链接或者执行其他动作时,JS 代码会再次调用 pushState 方法,将新页面的 URL 添加到历史记录中,并渲染对应的页面内容。此时历史记录中就保存有所有已经访问过的页面的 URL 信息,可以直接使用浏览器提供的回退和前进按键进行页面的快速访问。

下面是一个简单的示例:

// 监听浏览器地址栏变化
window.addEventListener('popstate', function(event) {
  console.log('location: ' + document.location + ', state: ' + JSON.stringify(event.state));
});

// 第一次进入页面时,添加当前 URL 到浏览器历史记录中
history.pushState({page: 1}, null, "?page=1");

// 用户点击页面链接时,添加新的 URL 到浏览器历史记录中,并更新页面内容
history.pushState({page: 2}, null, "?page=2");

// 用户点击回退按钮时,浏览器会回退到上一个已访问的页面(即 page=1)
window.history.back();

在history模式下,通过HTML5中提供的pushState()replaceState()方法,我们可以改变浏览器地址栏上的URL,并且在页面跳转时不会引起页面的刷新。举个例子,假设我们有一个简单的React单页应用程序:

<!DOCTYPE html>
<html>
<head>
  <title>A Simple React App</title>
</head>
<body>
  <div id="app"></div>

  <script src="https://cdn.jsdelivr.net/npm/react@17.0.2/umd/react.development.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/react-dom@17.0.2/umd/react-dom.development.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/react-router-dom@5.3.0/umd/react-router-dom.min.js"></script>

  <script>
    // 创建路由实例
    const { BrowserRouter, Route, Link } = window.ReactRouterDOM

    // 创建组件
    const Home = () => <div>这里是首页</div>;
    const About = () => <div>这里是关于我们</div>;

    // 渲染组件
    ReactDOM.render(
      <BrowserRouter>
        <Link to="/home">首页</Link>{' '}
        <Link to="/about">关于我们</Link>
        <Route path="/home" component={Home} />
        <Route path="/about" component={About} />
      </BrowserRouter>,
      document.querySelector('#app')
    )
  </script>
</body>
</html>

在这个例子中,我们使用React Router来实现前端路由,在浏览器地址栏上使用正常的URL格式。当用户点击不同的链接时,页面跳转但不会重新加载,相反,根据路由规则,对应的组件(Home或About)将被渲染。

综上所述,以上两种方式都可以实现前端路由的功能,开发者可以根据自己的需求选择合适的方式。