vue-router 源码:实现一个简单的 vue-router
前言
通过上篇,我们知道前端理由的两种实现方法,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-link
和 router-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 呢,先提供一下实现的思路:
- 绑定
hashchange
事件,实现前端路由; - 将传入的路由和组件做一个路由映射,切换哪个路由即可找到对应的组件显示;
- 需要 new 一个 Vue 实例还做响应式通信,当路由改变的时候,
router-view
会响应更新; - 注册
router-link
和router-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> 标签,点击它便能触发 hashchange
。router-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相关推荐
- fastslam matlab,fastslam 快速定位和构图的源码,一个简单的例子,3D建模,可以用作学习智能机器人自主移动 matlab 272万源代码下载- www.pudn.com...
文件名称: fastslam下载 收藏√ [ 5 4 3 2 1 ] 开发工具: matlab 文件大小: 31 KB 上传时间: 2015-03-19 下载次数: 22 详细说明:快速定 ...
- 搭建vue项目环境以及创建一个简单的vue的demo
一.vue-cli脚手架的搭建步骤 1.首先,确定你的电脑上已经安装了nodejs,可以使用npm包管理器安装环境,如果还没有安装node环境,则需要安装node.js 这个很简单 默认点击安装 ...
- 搭建Vue.js环境,建立一个简单的Vue项目
基于vue-cli快速构建 Vue是近年来比较火的一个前端框架,所以搭建Vue.js环境,要装webpack,vue-cli,Vue 安装webpack命令如下 $ cnpm install webp ...
- vue商城源码_一个标星 5.2k+ 的牛逼开源商城系统
关注上方"终端研发部",选择星标, 关键时间,第一时间送达! 来源:GitHub精选 大家好,我是于小二.今天推荐的这个项目是「newbee-mall」,这个名字乍一看我以为叫牛逼 ...
- HTML5源码-实现一个简单的个人主页
class="selected" 表示这个链接标签和其他链接标签有所不同 源代码: <!doctype html> <html> <head& ...
- 直播系统源码python 一个简单的网站采集
#!/usr/local/bin/python #coding=utf8 #网站定向简易采集 #QQ:29295842 import get_post import re import re, sys ...
- Vue.js 源码分析(九) 基础篇 生命周期详解
先来看看官网的介绍: 主要有八个生命周期,分别是: beforeCreate.created.beforeMount.mounted.beforeupdate.updated .beforeDes ...
- Dubbo 源码分析 - 集群容错之 Router
1. 简介 上一篇文章分析了集群容错的第一部分 – 服务目录 Directory.服务目录在刷新 Invoker 列表的过程中,会通过 Router 进行服务路由.上一篇文章关于服务路由相关逻辑没有细 ...
- Vue 3源码剖析,看这篇就够了
大家好,我是若川.源码的重要性相信不用再多说什么了吧,特别是用Vue 框架的,一般在面试的时候面试官多多少少都会考察源码层面的内容,比如: 如何理解虚拟Dom? Vue 3为什么这么快? Vue 3的 ...
- 【Vue.js源码解析 一】-- 响应式原理
前言 笔记来源:拉勾教育 大前端高薪训练营 阅读建议:建议通过左侧导航栏进行阅读 课程目标 Vue.js 的静态成员和实例成员初始化过程 首次渲染的过程 数据响应式原理 – 最核心的特性之一 准备工作 ...
最新文章
- MySQL数据库启动报The server quit without updating PID file
- Android而一个超级漂亮的日历控件
- 18-Chain of trust bindings
- 达摩院 2020 预测:工业互联网超融合来袭!
- [原]排错实战——拯救加载调试符号失败的IDA
- 用台球杆击球,这个击球力道能传递到10米之外的球上吗?
- 前端学习(3213):setstate的一个使用
- 北京市委书记蔡奇:加快拓展数字人民币应用全场景试点
- 查看本用户对文件的权限_Linux添加新用户,设置文件权限组
- java档案管理系统_基于JAVA的简单档案管理系统
- Unix编程艺术-原则
- Oracle + PlSql 下载安装配置
- excel同时冻结首行和首列怎么操作
- 如何制作纺织产品标签
- java 调色板的程序_java调色板的代码
- 鸿蒙判后而成翻译,我在洪荒一百四十六石猴出世(1/3)胜神州。东胜神洲,海外有一国土,名曰傲来-金羚文学...
- [ 重 新 预 习 ] Node.js搭建服务
- 模糊查询的hql语句_hql语句拼接模糊查询
- 2022-5月如何使用疯狂URL获取抖音推流码地址(抖音无人直播教程)
- vue中this.$confirm,确定和取消执行不同的逻辑处理