前言

通过上篇,我们知道前端理由的两种实现方法,Hash 路由与 History 路由,并且用它们分别实现了一个前端路由。

接下来我们就将 Vue 与 Hash 路由结合,实现一个非常简单的 vue-router 吧。

开始实现

想象一下,如果自己实现了一个 vue-router,会怎么去使用呢?参考 vue-router 官方的使用方式,看看 html 的使用:

<div id="app"><p><router-link to="#/">home</router-link><router-link to="#/book">book</router-link><router-link to="#/movie">movie</router-link></p><router-view></router-view>
</div>
复制代码

这里会有 router-linkrouter-view 两个组件需要我们来实现。再来看 js 的:

const Home = { template: '<div>home</div>' };
const Book = { template: '<div>book</div>' };
const Movie = { template: '<div>movie</div>' };const routes = [{ path: '/', component: Home },{ path: '/book', component: Book },{ path: '/movie', component: Movie }
];const router = new VueRouter(Vue, {routes
});new Vue({el: '#app'
});
复制代码

这里会有我们自己定义的组件 Home、Book 和 Movie,并且有它们各自对应的路由。我们实现的 VueRouter 跟官方的有些区别,在 VueRouter 被 new 时是将 Vue 作为参数传入,而不是注入挂载到根实例下。

接下来就是 VueRouter 的实现了。

VueRouter

要怎么来实现 VueRouter 呢,先提供一下实现的思路:

  1. 绑定 hashchange 事件,实现前端路由;
  2. 将传入的路由和组件做一个路由映射,切换哪个路由即可找到对应的组件显示;
  3. 需要 new 一个 Vue 实例还做响应式通信,当路由改变的时候,router-view 会响应更新;
  4. 注册 router-linkrouter-view 组件。

先创建一个 VueRouter:

class VueRouter {constructor (Vue, options) {this.$options = options;}
}
复制代码

绑定事件

给 VueRouter 添加一个绑定事件的方法,一旦路由发生改变,会触发 onHashChange 方法。

constructor (Vue, options) {this.init();
}// 绑定事件
init () {window.addEventListener('load', this.onHashChange.bind(this), false);window.addEventListener('hashchange', this.onHashChange.bind(this), false);
}
复制代码

路由映射表

将传入的 options 设置成一张路由映射表,以便于通过路由查找到对应的组件。

constructor (Vue, options) {this.$options = options;this.routeMap = {};this.createRouteMap(this.$options);
}// 路由映射表
createRouteMap (options) {options.routes.forEach(item => {this.routeMap[item.path] = item.component;});
}
复制代码

options 之中,路由与组件的关系:

const routes = [{ path: '/', component: Home },{ path: '/book', component: Book },{ path: '/movie', component: Movie }
];
复制代码

生成的路由映射表:

this.routeMap = {'/': Home,'/book': Book,'/movie': Movie
};
复制代码

响应

我们需要 new 一个新的 Vue 实例,将当前路由 current 储存在其 data 之中,当修改了 current 时,router-view 就会自己去更新视图。

constructor (Vue, options) {this.app = new Vue({data: {current: '#/'}});
}// 获取当前 hash 串
getHash () {return window.location.hash.slice(1) || '/';
}// 设置当前路径
onHashChange () {this.app.current = this.getHash();
}
复制代码

只要在 router-view 里使用到了 this.app.current,一旦更新它,便会更新。

注册组件

router-link 实际上就是一个 <a> 标签,点击它便能触发 hashchangerouter-view 会实现一个 render 方法,将当前路由对应的组件取出,进行渲染。

constructor (Vue, options) {this.initComponent(Vue);
}// 注册组件
initComponent (Vue) {Vue.component('router-link', {props: {to: String},template: '<a :href="to"><slot></slot></a>'});const _this = this;Vue.component('router-view', {render (h) {var component = _this.routeMap[_this.app.current];return h(component);}});
}
复制代码

完整代码

至此,一个简单的 vue-router 就出来了,全部代码是这样的:

class VueRouter {constructor (Vue, options) {this.$options = options;this.routeMap = {};this.app = new Vue({data: {current: '#/'}});this.init();this.createRouteMap(this.$options);this.initComponent(Vue);}// 绑定事件init () {window.addEventListener('load', this.onHashChange.bind(this), false);window.addEventListener('hashchange', this.onHashChange.bind(this), false);}// 路由映射表createRouteMap (options) {options.routes.forEach(item => {this.routeMap[item.path] = item.component;});}// 注册组件initComponent (Vue) {Vue.component('router-link', {props: {to: String},template: '<a :href="to"><slot></slot></a>'});const _this = this;Vue.component('router-view', {render (h) {var component = _this.routeMap[_this.app.current];return h(component);}});}// 获取当前 hash 串getHash () {return window.location.hash.slice(1) || '/';}// 设置当前路径onHashChange () {this.app.current = this.getHash();}
}
复制代码

最后

将 Vue 与 Hash 路由结合,监听了 hashchange 事件,再通过 Vue 的 响应机制组件,便有了上面实现好了一个 vue-router。

全部源码参考 这里。

vue-router 源码:实现一个简单的 vue-router相关推荐

  1. fastslam matlab,fastslam 快速定位和构图的源码,一个简单的例子,3D建模,可以用作学习智能机器人自主移动 matlab 272万源代码下载- www.pudn.com...

    文件名称: fastslam下载  收藏√  [ 5  4  3  2  1 ] 开发工具: matlab 文件大小: 31 KB 上传时间: 2015-03-19 下载次数: 22 详细说明:快速定 ...

  2. 搭建vue项目环境以及创建一个简单的vue的demo

    一.vue-cli脚手架的搭建步骤 1.首先,确定你的电脑上已经安装了nodejs,可以使用npm包管理器安装环境,如果还没有安装node环境,则需要安装node.js 这个很简单    默认点击安装 ...

  3. 搭建Vue.js环境,建立一个简单的Vue项目

    基于vue-cli快速构建 Vue是近年来比较火的一个前端框架,所以搭建Vue.js环境,要装webpack,vue-cli,Vue 安装webpack命令如下 $ cnpm install webp ...

  4. vue商城源码_一个标星 5.2k+ 的牛逼开源商城系统

    关注上方"终端研发部",选择星标, 关键时间,第一时间送达! 来源:GitHub精选 大家好,我是于小二.今天推荐的这个项目是「newbee-mall」,这个名字乍一看我以为叫牛逼 ...

  5. HTML5源码-实现一个简单的个人主页

    class="selected" 表示这个链接标签和其他链接标签有所不同     源代码: <!doctype html> <html> <head& ...

  6. 直播系统源码python 一个简单的网站采集

    #!/usr/local/bin/python #coding=utf8 #网站定向简易采集 #QQ:29295842 import get_post import re import re, sys ...

  7. Vue.js 源码分析(九) 基础篇 生命周期详解

    先来看看官网的介绍: 主要有八个生命周期,分别是: beforeCreate.created.beforeMount.mounted.beforeupdate.updated   .beforeDes ...

  8. Dubbo 源码分析 - 集群容错之 Router

    1. 简介 上一篇文章分析了集群容错的第一部分 – 服务目录 Directory.服务目录在刷新 Invoker 列表的过程中,会通过 Router 进行服务路由.上一篇文章关于服务路由相关逻辑没有细 ...

  9. Vue 3源码剖析,看这篇就够了

    大家好,我是若川.源码的重要性相信不用再多说什么了吧,特别是用Vue 框架的,一般在面试的时候面试官多多少少都会考察源码层面的内容,比如: 如何理解虚拟Dom? Vue 3为什么这么快? Vue 3的 ...

  10. 【Vue.js源码解析 一】-- 响应式原理

    前言 笔记来源:拉勾教育 大前端高薪训练营 阅读建议:建议通过左侧导航栏进行阅读 课程目标 Vue.js 的静态成员和实例成员初始化过程 首次渲染的过程 数据响应式原理 – 最核心的特性之一 准备工作 ...

最新文章

  1. MySQL数据库启动报The server quit without updating PID file
  2. Android而一个超级漂亮的日历控件
  3. 18-Chain of trust bindings
  4. 达摩院 2020 预测:工业互联网超融合来袭!
  5. [原]排错实战——拯救加载调试符号失败的IDA
  6. 用台球杆击球,这个击球力道能传递到10米之外的球上吗?
  7. 前端学习(3213):setstate的一个使用
  8. 北京市委书记蔡奇:加快拓展数字人民币应用全场景试点
  9. 查看本用户对文件的权限_Linux添加新用户,设置文件权限组
  10. java档案管理系统_基于JAVA的简单档案管理系统
  11. Unix编程艺术-原则
  12. Oracle + PlSql 下载安装配置
  13. excel同时冻结首行和首列怎么操作
  14. 如何制作纺织产品标签
  15. java 调色板的程序_java调色板的代码
  16. 鸿蒙判后而成翻译,我在洪荒一百四十六石猴出世(1/3)胜神州。东胜神洲,海外有一国土,名曰傲来-金羚文学...
  17. [ 重 新 预 习 ] Node.js搭建服务
  18. 模糊查询的hql语句_hql语句拼接模糊查询
  19. 2022-5月如何使用疯狂URL获取抖音推流码地址(抖音无人直播教程)
  20. vue中this.$confirm,确定和取消执行不同的逻辑处理

热门文章

  1. C++原型模式和模板模式
  2. hdu5033 Building 单调队列
  3. Anaconda使用入门
  4. develop note 1
  5. (笔试题)被3和5整除的数的和
  6. fg、bg、jobs、、ctrl + z命令
  7. iOS duplicate symbols for architecture x86_64 问题全面解析
  8. Hibernate Annotation 设置字段的默认值
  9. 权限管理系统之软件注册模块
  10. 如何查看SharePoint Server的版本信息