≡
  • 网络编程
  • 数据库
  • CMS技巧
  • 软件编程
  • PHP笔记
  • JavaScript
  • MySQL
位置:首页 > 网络编程 > vue.js

vue-router 源码实现前端路由的两种方式

人气:423 时间:2019-04-11

这篇文章主要为大家详细介绍了vue-router 源码实现前端路由的两种方式,具有一定的参考价值,可以用来参考一下。

感兴趣的小伙伴,下面一起跟随四海网的小编两巴掌来看看吧!

在学习 vue-router 的代码之前,先来简单了解一下前端路由。

前端路由主要有两种实现方法:

  • Hash 路由
  • History 路由

先来看看这两种方法的实现原理。

接着我们将用它们来简单实现一个自己的前端路由。

 

前端路由

 

 

Hash 路由

 

url 的 hash 是以 # 开头,原本是用来作为锚点,从而定位到页面的特定区域。当 hash 改变时,页面不会因此刷新,浏览器也不会向服务器发送请求。

http://www.xxx.com/#/home

同时, hash 改变时,并会触发相应的 hashchange 事件。所以,hash 很适合被用来做前端路由。当 hash 路由发生了跳转,便会触发 hashchange 回调,回调里可以实现页面更新的操作,从而达到跳转页面的效果。

代码如下:


window.addEventListener('hashchange', function () {
 console.log('render');
});

 

History 路由

 

HTML5 规范中提供了 history.pushState 和 history.replaceState 来进行路由控制。通过这两个方法,可以实现改变 url 且不向服务器发送请求。同时不会像 hash 有一个 # ,更加的美观。但是 History 路由需要服务器的支持,并且需将所有的路由重定向到根页面。

History 路由的改变不会去触发某个事件,所以我们需要去考虑如何触发路由更新后的回调。

有以下两种方式会改变 url:

  • 调用 history.pushState 或 history.replaceState;
  • 点击浏览器的前进与后退。

第一个方式可以封装一个方法,在调用 pushState(replaceState)后再调用回调。

代码如下:


function push (url) {
 window.history.pushState({}, null, url);
 handleHref();
}

function handleHref () {
 console.log('render');
}

第二个方式,浏览器的前进与后退会触发 popstate 事件。

代码如下:


window.addEventListener('popstate', handleHref);

路由实现

我们通过 <a> 标签来进行切换路由,通过一个 <div> 标签来装载各路由对应的页面内容。

参考 vue-router 的调用,我们会这么地调用一个 Router ,将路由与对应组件作为参数传入:

代码如下:



const router = new Router([
 {
  path: '/',
  component: 'home'
 },
 {
  path: '/book',
  component: 'book'
 },
 {
  path: '/movie',
  component: 'movie'
 }
]);

数组里是各路由对应的要显示的内容,接下来就来开始实现这个 Router 。

 

Hash 路由实现

 

Hash 路由 <a> 标签都需要带上 # :

代码如下:



<div>
 <a href="#/" rel="external nofollow" >home</a>
 <a href="#/book" rel="external nofollow" >book</a>
 <a href="#/movie" rel="external nofollow" >movie</a>
  
 <div id="content"></div>
</div>

Router 的代码实现如下:

代码如下:



class Router {
 constructor (options) {
  this.routes = {};
  
  this.init();
  
  // 遍历,绑定视图更新
  options.forEach(item => {
   this.route(item.path, () => {
   	document.getElementById('content').innerHTML = item.component;
   });
  });
 }
 
 // 绑定监听事件
 init () {
  window.addEventListener('load', this.updateView.bind(this), false);
  window.addEventListener('hashchange', this.updateView.bind(this), false);
 }
 
 // 更新试图
 updateView () {
  const currentUrl = window.location.hash.slice(1) || '/';
  this.routes[currentUrl] && this.routes[currentUrl]();
 }
 
 // 将路由与回调函数关联
 route (path, cb) {
  this.routes[path] = cb;
 }
}

实现效果如下:

 

 
【图片暂缺】 

 

History 路由实现

History 路由需要服务器的支持,可以点击这里 的代码参考。

代码如下:



<div>
 <a href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" data-href="/" rel="external nofollow" >home</a>
 <a href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" data-href="/book" rel="external nofollow" >book</a>
 <a href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" data-href="/movie" rel="external nofollow" >movie</a>
  
 <div id="content"></div>
</div>

Router 的代码实现如下:

代码如下:



class Router {
 constructor (options) {
  this.routes = {};

  this.init();
  this.bindEvent();

  // 遍历,绑定视图更新
  options.forEach(item => {
   this.route(item.path, () => {
    document.getElementById('content').innerHTML = item.component;
   });
  });
 }

 // 绑定点击事件
 bindEvent () {
  const _this = this;
  const links = document.getElementsByTagName('a');

  [].forEach.call(links, link => {
   link.addEventListener('click', function () {
    const url = this.getAttribute('data-href');
    _this.push(url);
   });
  });
 }

 // 绑定监听事件
 init () {
  window.addEventListener('load', this.updateView.bind(this), false);
  window.addEventListener('popstate', this.updateView.bind(this), false);
 }

 push (url) {
  window.history.pushState({}, null, url);
  this.updateView();
 }

 // 更新试图
 updateView () {
  const currentUrl = window.location.pathname || '/';
  this.routes[currentUrl] && this.routes[currentUrl]();
 }

 // 将路由与回调函数关联
 route (path, cb) {
  this.routes[path] = cb;
 }
}

实现效果如下:

 

 
【图片暂缺】

 

最后

前端路由实现方式有两种,分别是:

  1. Hash 路由
  2. History 路由

原理都是修改 url 的同时不刷新页面,不向服务器发送请求,通过监听特殊的事件来更新页面。

以上实现全部源码参考这里。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持四海网。

本文来自:http://www.q1010.com/184/5333-0.html

注:关于vue-router 源码实现前端路由的两种方式的内容就先介绍到这里,更多相关文章的可以留意四海网的其他信息。

关键词:vue.js

您可能感兴趣的文章

  • vue awesome swiper异步加载数据出现的bug问题
  • vue 解决addRoutes动态添加路由后刷新失效问题
  • 浅析vue.js数组的变异方法
  • 关于Vue组件库开发详析
  • Vue props用法分析(小结)
  • vue v-model动态生成分析
  • vue中的数据绑定原理的实现
  • 解析vue data不可以使用箭头函数问题
  • VUE 3D轮播图封装实现方法
  • 解决vue项目打包后提示图片文件路径错误的问题
上一篇:分析Vue SPA项目优化小记
下一篇:Vue props用法分析(小结)
热门文章
  • Vue 报错TypeError: this.$set is not a function 的解决方法
  • vue实现动态添加数据滚动条自动滚动到底部的示例代码
  • vue项目设置scrollTop不起作用(总结)
  • vue项目中使用vue-i18n报错的解决方法
  • iview实现select tree树形下拉框的示例代码
  • 分析关于element级联选择器数据回显问题
  • vue项目打包后打开页面空白解决办法
  • 解决element ui select下拉框不回显数据问题的解决
  • element-ui table span-method(行合并)的实现代码
  • element-ui 设置菜单栏展开的方法
  • 最新文章
    • 理解vue ssr原理并自己搭建简单的ssr框架
    • vue favicon设置以及动态修改favicon的方法
    • vue-router启用history模式下的开发及非根目录部署方法
    • 从零开始在NPM上发布一个Vue组件的方法步骤
    • Element input树型下拉框的实现代码
    • Vue 报错TypeError: this.$set is not a function 的解决方法
    • Vue.js组件高级特性实例分析
    • 浅谈VueJS SSR 后端绘制内存泄漏的相关解决经验
    • 分析Vue.js自定义tipOnce指令用法实例
    • 浅谈vuex actions和mutation的异曲同工

四海网收集整理一些常用的php代码,JS代码,数据库mysql等技术文章。