博客列表 >使用原生 js 和 Vue 路由模块分别实现一个前端路由

使用原生 js 和 Vue 路由模块分别实现一个前端路由

祥子弟弟
祥子弟弟原创
2021年02月11日 23:57:581163浏览

前端路由:通过动态改变 url 实现,并不会和后端服务器发生交互,前端路由不同于传统路由,它不需要服务器来进行解析,而是通过一个 hash 函数或者 H5 提供的 history API 来实现。
前端路由的优势:页面刷新速度快。由于前端路由不需要和后端服务器发生交互,省略了请求的过程,且不会受到网络延迟的影响,所以它的刷新速度快,用户体验好。

使用原生 js 完成前端路由

1.基于锚点的哈希路由
通过\<a>标签改变 URL,然后使用 hashchange 事件监听 URL 的变动,hash 是 URL 中 hash (#) 及后面的那部分,常用作锚点在页面内进行导航,改变 URL 中的 hash 部分不会引起页面刷新。

html

  1. <body>
  2. <nav>
  3. <!-- 此时的#list1,#list2就是锚点 -->
  4. <a href="#/list1">娱乐新闻</a>
  5. <a href="#/list2">体育新闻</a>
  6. </nav>
  7. <!-- 该区域专用于显示路由的内容 -->
  8. <div class="route-view"></div>
  9. </body>

js

  1. // 获取路由内容显示区元素
  2. const routeView = document.querySelector(".route-view");
  3. // 锚点使用 location.hash
  4. // window.location: 描述的是当前url信息
  5. // console.log(location.hash);
  6. // hashchange事件:url中的锚点变化时会自动触发这个事件
  7. window.addEventListener("hashchange", show);
  8. // load事件:要等js执行完成和图片加载完成才能触发
  9. // window.addEventListener("load", show);
  10. // DOMContentLoaded事件: 只要dom树创建完成就会触发
  11. window.addEventListener("DOMContentLoaded", show);
  12. let list1 = `
  13. <ul>
  14. <li><a href="">娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻</a></li>
  15. <li><a href="">娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻</a></li>
  16. <li><a href="">娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻</a></li>
  17. </ul>`;
  18. let list2 = `<ul>
  19. <li><a href="">体育新闻体育新闻体育新闻体育新闻体育新闻体育新闻体育新闻</a></li>
  20. <li><a href="">体育新闻体育新闻体育新闻体育新闻体育新闻体育新闻体育新闻</a></li>
  21. <li><a href="">体育新闻体育新闻体育新闻体育新闻体育新闻体育新闻体育新闻</a></li>
  22. </ul>`;
  23. function show() {
  24. console.log(location.hash);
  25. switch (location.hash) {
  26. case "#/list1":
  27. routeView.innerHTML = list1;
  28. break;
  29. case "#/list2":
  30. routeView.innerHTML = list2;
  31. break;
  32. default:
  33. routeView.innerHTML = list1;
  34. }
  35. }

实现效果

2.基于历史记录的路由
在 H5 中提供了 history API,通过 history 的 pushState 方法来实现。

html

  1. <body>
  2. <nav class="app">
  3. <a href="/list1">娱乐新闻</a>
  4. <a href="/list2">体育新闻</a>
  5. </nav>
  6. <div class="router-view"></div>
  7. </body>

js

  1. const list1 = `
  2. <ul>
  3. <li><a href="">娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻</a></li>
  4. <li><a href="">娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻</a></li>
  5. <li><a href="">娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻</a></li>
  6. </ul>`;
  7. const list2 = `<ul>
  8. <li><a href="">体育新闻体育新闻体育新闻体育新闻体育新闻体育新闻体育新闻</a></li>
  9. <li><a href="">体育新闻体育新闻体育新闻体育新闻体育新闻体育新闻体育新闻</a></li>
  10. <li><a href="">体育新闻体育新闻体育新闻体育新闻体育新闻体育新闻体育新闻</a></li>
  11. </ul>`;
  12. const routerView = document.querySelector(".router-view");
  13. // 获取到所有的a.href
  14. const links = document.querySelectorAll(".app a[href]");
  15. // console.log(links);
  16. links.forEach(
  17. (link) =>
  18. (link.onclick = (ev) => {
  19. // 禁用掉a标签的默认行为
  20. ev.preventDefault();
  21. // history对象,history.pushState(data状态对象,title标题, url)
  22. history.pushState(null, "", link.href);
  23. // 手工更新了url,但是popstate事件监听不到这个变化,需要这里调用一个函数
  24. show();
  25. })
  26. );
  27. window.addEventListener("DOMContentLoaded", show);
  28. // 当整个页面及所有依赖资源如样式表和图片都已完成加载时,将触发load事件。
  29. // 它与DOMContentLoaded不同,后者只要页面DOM加载完成就触发,无需等待依赖资源的加载。
  30. function show() {
  31. console.log(location.pathname);
  32. switch (location.pathname) {
  33. case "/list1":
  34. routerView.innerHTML = list1;
  35. break;
  36. case "/list2":
  37. routerView.innerHTML = list2;
  38. break;
  39. default:
  40. routerView.innerHTML = list1;
  41. }
  42. }

运行结果

使用 Vue 路由模块分别实现一个前端路由

vue 路由是基于 hash 实现的,是用 a 标签的锚点来实现的。在原生 js 中是通过 a 标签的 href 属性来跳转,而在 vue 中则是通过 to 属性来跳转。

使用 Vue 的路由模块来实现路由,首先需要的是下载好路由模块,在github上下载下来。然后通过 script 标签导入路由模块。然后创建一个路由,再将这个路由挂载到Vue的挂载点上。

html

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>vue路由原理与实现</title>
  7. <!-- 加载vue框架 -->
  8. <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  9. <!-- 加载路由模块 -->
  10. <script src="../vue-router-dev/dist/vue-router.js"></script>
  11. </head>
  12. <body>
  13. <nav class="app">
  14. <router-link to="/list1">娱乐新闻</router-link>
  15. <router-link to="/list2">体育新闻</router-link>
  16. <!-- 路由到的资源显示区域 -->
  17. <router-view></router-view>
  18. </nav>
  19. <script>
  20. const list1 = {
  21. // 组件模板字面量
  22. template: `
  23. <ul>
  24. <li><a href="">娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻</a></li>
  25. <li><a href="">娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻</a></li>
  26. <li><a href="">娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻娱乐新闻</a></li>
  27. </ul>`,
  28. };
  29. const list2 = {
  30. template: `<ul>
  31. <li><a href="">体育新闻体育新闻体育新闻体育新闻体育新闻体育新闻体育新闻</a></li>
  32. <li><a href="">体育新闻体育新闻体育新闻体育新闻体育新闻体育新闻体育新闻</a></li>
  33. <li><a href="">体育新闻体育新闻体育新闻体育新闻体育新闻体育新闻体育新闻</a></li>
  34. </ul>`,
  35. };
  36. // 1.创建路由对象
  37. const router = new VueRouter({
  38. // 路由配置项
  39. routes: [
  40. // 每一个路由都是一个对象,每个对象对应着一个路由地址
  41. {
  42. // path:路由路径
  43. path: "/list1",
  44. // 路由组件
  45. component: list1,
  46. },
  47. {
  48. path: "/list2",
  49. component: list2,
  50. },
  51. ],
  52. });
  53. // 2. 注册路由
  54. new Vue({
  55. el: ".app",
  56. router: router,
  57. }).$mount(".app");
  58. </script>
  59. </body>
  60. </html>

在设置路由配置项时,routes是一个对象数组,里边的元素都是以对象的方式存在的,每一个对象就是一个路由,每个对象也都对应着一个路由地址。

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议