主要是思路,自己定义组件的时候可以借鉴

Vue-router的 类图

  • name
  • options: ==> 记录构造函数中传入的对象,在 new VueRouter的时候传了一个对象( routes :路由规则)
  • data: ==> 有个属性 current (记录当前路由地址的),响应式的数据(地址变化加载不同的组件),需要 Vue.observable方法
  • routeMap: ==> 一个对象,记录路由地址和组件的对应关系,解析路由规则到 routeMap

  • Constructor(Options):VueRouter
  • _install(Vue):void => 静态方法,实现 Vue 的插件机制
  • init():void ==> init 方法调用下面3个方法,不同的代码分割到不同的方法中实现
  • initEvent():void => 注册 popState 方法,监听浏览器历史的变化
  • initRouteMap():void => 初始化 routeMap 属性,把构造函数中传入的路由规则转换成键值对的形式存储到 RouteMap({key:path, value:component})中,我们在 router-view 这个组件中会使用这个 routeMap
  • initComponents(Vue):void => 用来创建 router-viewrouter-link 这两个组件的

Vue 的构建版本

  • 运行时版: 不支持 template模板, 需要打包的时候提前编译 -Vue-Cli 创建时默认值, 需要手写 render函数
  • 完整版: 包含运行时和编译器, 体积比运行时版大10K左右, 程序运行时把模板转换成render函数
  • pushState 就是改变浏览器地址
let _Vue = null
export default class VueRouter {
// ----------------------------------- install section -----------------------------------
static install(Vue) {
// 1.判断当前插件是否已经安装
if (VueRouter.install.installed) {
return
}
// 插件被安装了
VueRouter.install.installed = true
// 2.把Vue的构造函数记录到全局变量
_Vue = Vue // 3.把创建Vue实例时候传入的router对象注入到Vue实例上(构造函数的原型上新增一个成员,这样所有的实例都可以访问到 $router)
// _Vue.prototype.$router = this.$options.router // 谁调用 this 就是谁, VueRouter.install()调用, 所以不是 Vue 实例,而是VueRouter这个类
// 混入
_Vue.mixin({
beforeCreate() {
// 这个混入会导致所有的组件都会有,会被执行很多次, 我们只需要执行一次
// 如果是组件的话就不执行了,如果是Vue实例才执行
// 判断条件: $options.router是否存在, 只有在 Vue.$options才有这个属性,而组件中没有这个属性
if (this.$options.router) {
_Vue.prototype.$router = this.$options.router // 在这里就是 Vue 实例 // 插件注册成功后执行
this.$options.router.init()
}
}
})
} // ----------------------------------- constructor section -----------------------------------
constructor(options) {
this.options = options
this.routeMap = {} // 键值对对象 路由: 组件
this.data = _Vue.observable({ // 响应式数据
current: '/'
})
} // ----------------------------------- initRouteMap section -----------------------------------
/**
* 作用: 把构造函数传进来的选项中 routes 转换成键值对的形式存储到 routeMap这个对象中 键值对对象 路由: 组件
*/
initRouteMap() {
// 遍历 路由规则 转换成键值对的形式存储到 routeMap这个对象中
this.options.routes.forEach(route => {
this.routeMap[route.path] = route.component
})
} // ----------------------------------- initComponents section -----------------------------------
/**
* 创建 router-link:
* 创建 router-view:
* 参数: Vue的构造函数,可以不传递,我们有全局变量记录,为了减少外部依赖最好传递
*/
initComponents(Vue) {
Vue.component('router-link', {
props: {
to: String
},
// template: '<a :href="to"><slot></slot></a>'
/**
* h 这个函数的作用创建 虚拟DOM
*/
render(h) {
// 参数1: 选择器, 参数2: 属性, 参数3: 子元素
return h('a', {
attrs: {
href: this.to // 不加 # 以 history模式
},
on: {
click: this.clickHanlder // 注册事件,不加括号
}
}, [this.$slots.default])
},
methods: {
clickHanlder(e) {
// data, title, url
history.pushState({}, '', this.to)
this.$router.data.current = this.to
e.preventDefault()
}
}
})
// 暂存 Vue对象
const self = this
Vue.component('router-view', {
render(h) {
// self.data.current // 当前路由地址
const component = self.routeMap[self.data.current]
return h(component)
}
})
} // ----------------------------------- init section -----------------------------------
// 包装 initComponents 和 initRouteMap
init() {
this.initRouteMap()
this.initComponents(_Vue)
this.initEvent()
} // ----------------------------------- initEvent -----------------------------------
// 箭头函数不会改变this的指向,initEvent的this就是VueRouter
initEvent() {
window.addEventListener('popstate', () => {
this.data.current = window.location.pathname
})
}
}

Vue 自定义VueRouter-简版的更多相关文章

  1. vue路由vue-router的使用

    对于单页应用,官方提供了vue-router进行路由跳转的处理. 安装 基于传统,我更喜欢采用npm包的形式进行安装. npm install vue-router --save 当然,官方采用了多种 ...

  2. java语言实现简单接口工具--粗简版

    2016注定是变化的一年,忙碌.网红.项目融资失败,现在有点时间整整帖子~~ 目标: 提高工作效率与质量,能支持平台全量接口回归测试与迭代测试也要满足单一接口联调测试. 使用人员: 测试,开发 工具包 ...

  3. use vue vuex vue-router, not use webpack

    vue,vuex,vue-router放在一起能做什么?不用webpack之类的打包工具使用他们是否可行?各位道友在初学vue时是否有这样的困惑.因为现代构建前端项目的一般模式是: 安装webapck ...

  4. [ABP开源项目]--vue+vuex+vue-router+EF的权限管理系统

    好久没写文字了,当然大家也不期待嘛,反正看代码就行了. 演示网站 首先说下这个项目吧. 如标题一样是基于VUE+.NET开发的框架,也是群友一直吼吼吼要一个vue版本的ABP框架. 我们先来看看首页吧 ...

  5. Vue路由vue-router

    前面的话 在Web开发中,路由是指根据URL分配到对应的处理程序.对于大多数单页面应用,都推荐使用官方支持的vue-router.Vue-router通过管理URL,实现URL和组件的对应,以及通过U ...

  6. Vue之VueRouter

    Vue之VueRouter实现原理 <!DOCTYPE html> <html lang="en"> <head> <meta chars ...

  7. Virtex6 PCIe 超简版基础概念学习(二)

    Virtex6 PCIe 超简版基础概念学习(二) 分类:FPGAPCIe (2081)  (0)  举报  收藏 文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 ise14.7 ...

  8. Vue自定义指令和路由

    一.自定义指令 除了默认设置的核心指令( v-model 和 v-show ), Vue 也允许注册自定义指令. 下面我们注册一个全局指令 v-focus,该指令的功能是在页面加载时,元素获得焦点: ...

  9. SpringBoot2+Netty打造通俗简版RPC通信框架(升级版)

    背景         上篇文章我简单的介绍了自己打造的通俗简版RPC通信框架,这篇是对简版的增强~         如果大家对此项目还感兴趣的话,可到码云上瞄瞄:Netty-RPC         上 ...

  10. SpringBoot2+Netty打造通俗简版RPC通信框架

    2019-07-19:完成基本RPC通信! 2019-07-22:优化此框架,实现单一长连接! 2019-07-24:继续优化此框架:1.增加服务提供注解(带版本号),然后利用Spring框架的在启动 ...

随机推荐

  1. java面试题jvm字节码的加载与卸载

    虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验,转换分析和初始化,最终形成可以被虚拟节直接使用的JAVA类型,这就是虚拟机的类加载机制. 类从被加载到虚拟机内存到卸载出内存的生命周期 ...

  2. 系统部署时的Could not load file or assembly 'Microsoft.VisualStudio.Enterprise.ASPNetHelper问题

    在web.config中,如下代码段 <compilation debug="true" targetFramework="4.0" assemblyPo ...

  3. Goorm永久免费的VPS

    简介 咱在LOC(某知名主机论坛)看到的,当个容器玩玩还是不错的,不过10分钟后会休眠,目前还没有大佬可以解决,可以使用SSH连接,适合折腾,不适合建站等生产环境操作,请注意.https://www. ...

  4. 题解 洛谷 P3340 【[ZJOI2014]星系调查】

    根据题意,发现题目中的图,其实就是一颗树或者是一颗基环树,每个节点上有一个点对\((x,y)\),每次询问为给定端点,找一条直线到端点间的所有点的距离之和最小. 设这条直线为\(y=kx+b\),根据 ...

  5. 分布式ID生成服务,真的有必要搞一个

    目录 阐述背景 Leaf snowflake 模式介绍 Leaf segment 模式介绍 Leaf 改造支持RPC 阐述背景 不吹嘘,不夸张,项目中用到ID生成的场景确实挺多.比如业务要做幂等的时候 ...

  6. Dart语言之 异步支持

    Dart类库有非常多的返回Future或者Stream对象的函数. 这些函数被称为异步函数:它们只会在设置好一些耗时操作之后返回,比如像 IO操作.而不是等到这个操作完成. async和await关键 ...

  7. Mybatis(一)Mybatis简介与入门程序

    Mybatis简介: MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动.创建connection.创建 ...

  8. spring学习(三)属性注入

    用的是IDEA的maven工程,pom.xml文件导包依赖省略 本文主要写set方式注入 (一).一般类型注入 一.写两个实体类Car.User public class Car { private ...

  9. [Jarvisos]Tell me something

    0x01 拿到题目首先检查一下是32位还是64位 64位程序,未开启canary栈保护 运行一下程序,检查一下程序的运行逻辑 提示->输入->输出 0x02 ida反编译一下,看一下代码逻 ...

  10. Java线程-- 线程池

    1.线程池概念 线程池,其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源. 为什么要使用线程池? 在java中,如果每个请求到达就创 ...