Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >vue-router原理分析与实践

vue-router原理分析与实践

作者头像
程序员老鱼
发布于 2022-12-02 01:53:05
发布于 2022-12-02 01:53:05
24100
代码可运行
举报
文章被收录于专栏:前端实验室前端实验室
运行总次数:0
代码可运行

将前端实验室设为星标精品文章第一时间阅读

大家好,我是前端实验室的大师兄!

今天大师兄跟大家简单聊聊Router的实现原理,以及我们如何去实现这样一个插件。

Vue RouterVue.js官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。关于Vue Router的使用就不做过多介绍了,大家可以前往Vue Router官网去学习哦~

vue-router插件的基本使用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const router = new Router({routes:[]})
export default router

import router from './route'
new Vue({
    render: h => h(APP),
    router
})

从上述代码可以看出,router也是作为一个插件去使用的,所以在进行原理实践时候,我们开发的就是一个插件。

插件开发思路

定义一个Router类,用来进行所有的router操作。定义一个install方法,将router挂载到Vue的实例上去。

注册全局组件router-linkrouter-viewrouter-link组件解析为一个a标签,router-view解析为一个div标签,内容为当前路由对应的component。

监听hashchange事件来改变当前路由对应的component,监听load事件做同样的事情。

对于嵌套路由而言,在渲染router-view时候,先去判断当前router-view的深度,即当前router-view是处在哪个层级,然后在解析routes时候判断当前路由。

如果当前路由和routes中某个路由都为'/'根路由,则直接放到路由渲染数组中,如果当前路由不是根路由,并且routes中的某个路由包含当前路由,则意味着routes数组中的这个路由要么是当前路由的父路由,要么就是当前路由。

然后把routes数组中的这个路由放到路由渲染数组中去,放完之后如果还有childrens,递归去做就行。

最后得到了一个路由匹配数组,这个数组里面包含当前路由和当前路由的父路由,并且数组中子路由的下标与之前router-view的层级下标相等,这样就能正确的将子路由的component正确的渲染到对应的router-view中去了。

譬如当前路由表如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
routes:[
    {
        path: '/',
        component: () => import ('../views/index.vue')
    },
    {
        path: '/second',
        component: () => import ('../views/second.vue'),
        childrens: [
            {
                path: '/seconde/article',
                component: import ('../view/article.vue')
            }
        ]
    }
]

此时second组件下有一个router-view,用来渲染子路由——article组件,在app下还有一个父router-view,用来渲染index、second组件,所以此时second组件下的router-view的层级是1(初始化为0)。

如果此时浏览器访问路由 /second/article 时候,触发我们的路由匹配方法,遍历routes数组和当前路由对比,当前路由不是根路由,并且包含 /second 路由,所以path为 /second 的选项被push进入路由渲染数组中,然后此路由还有childrens,进行递归,好家伙,当前路由和 /second/article 完全相等,所以也被push到了渲染数组中。

最后我们得到了一个数组,包含两个路由选项,父路由下标0,子路由下标1,之前我们也将router-view做了层级标记,这样就能得到子router-view对应渲染的component了。~nice

插件开发

先来一个cRouter文件夹,下面搞一个index.js,里面就是我们传统的router使用,上面有,然后再搞一个crouter.js:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import Link from './cLink'
import View from './cView'
var Vue

class cRouter {
  constructor(options) {
        this.$options = options
    this.courrentRoute = window.location.hash.slice(1) || '/'
    //定义一个响应式的路由渲染数组
        Vue.util.defineReactive(this,'routeMap',[])
        // 遍历匹配路由
    this.initRouterMap()
    // 初始化route改变事件
    this.initRouteChange()
  }
 
  initRouterMap(route) {
        let routes = route || this.$options.routes
        for (const routeItem of routes) {
            if (this.courrentRoute === '/' && routeItem.path === '/') {
                this.routeMap.push(routeItem)
                return
            }

            if (
            routeItem.path !== '/'
            && 
            this.courrentRoute.indexOf(routeItem.path) !== -1) {
                this.routeMap.push(routeItem)
                if (routeItem.childrens && routeItem.childrens.length > 0) {
                    this.initRouterMap(routeItem.childrens)
                }
                return
            }
        }
  }

  initRouteChange() {
    window.addEventListener('hashchange', this.routeChange.bind(this))
    window.addEventListener('load', this.routeChange.bind(this))
  }

  routeChange() {
        this.courrentRoute = window.location.hash.slice(1)
        this.routeMap = []
    this.initRouterMap()
  }
}

function install(_Vue) {
  Vue = _Vue

  Vue.mixin({
    beforeCreate() {
      if (this.$options.crouter) {
        Vue.prototype.$crouter = this.$options.crouter
      }
    },
  })

  Vue.component('router-link', Link)

  Vue.component('router-view', View)
}

export default {
  cRouter,
  install,
}

cview.js用来渲染router-view

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export default {
    render(h) {
        // 将自身标记为一个router-view,避免和其他元素搞混
        this.$vnode.data.routerView = true
        let parent = this.$parent
        //默认自己层级为0
        let routeDeep = 0

        while(parent) {
            // 判断是否存在父元素并且父元素有值
            const vodeData = parent.$vnode && parent.$vnode.data
            if (vodeData) {
                // 如果父router-view是true,则自身层级增加
                if (vodeData.routerView) {
                    routeDeep++
                }
            }
            //继续寻找父元素,进行递归
            parent = parent.$parent
        }

        let component = null
        const route = this.$crouter.routeMap[routeDeep]
        if (route) {
            component = route.component
        }
        return h(component)
    }
}

cLink.js用来渲染router-link

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export default {
    props: {
        to: {
            type: String,
            default: '/',
        },
    },
    render(h) {
        return h(
            'a',
            { attrs: { href: `#${this.to}` } },
            this.$slots.default
        )
    }
}

文章到这里,我们简单实现了类似vue aouter路由的功能,赶紧公众号回复「vue-router」获取相关示例源码哦~

大师兄想说的是:如今开源框架大大方便了我们的开发效率,但是单纯的使用三方框架并不能让我们学到更多知识

我们应该是研究去探索他的实现原理以及设计理念,去思考如果让我们设计一个框架,我们需要掌握哪些知识,该如何设计? 我想,这样的学习才能学到更多的知识~

原创不易,如文章对你有帮助,你的点赞、留言、分享就是大师兄写下去的动力!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Jetson Nano 使用gSOAP生成ONVIF框架代码及动态库 -- 3 ONVIF 动态库生成
使用sudo cp dom.c samples/onvif/命令,拷贝dom.c文件
DN
2020/07/06
2K0
Jetson Nano 使用gSOAP生成ONVIF框架代码及动态库 -- 3  ONVIF 动态库生成
Jetson Nano 使用gSOAP生成ONVIF框架代码及动态库 -- 2 ONVIF框架生成
由于使用gSOAP版本为2.8.102,需要对typemap.dat文件进行修改,否则会在后面动态库生成中提示错误,错误如下所示:
DN
2020/07/06
1.8K0
Jetson Nano 使用gSOAP生成ONVIF框架代码及动态库 -- 2  ONVIF框架生成
Qt音视频开发27-Onvif设备搜索
最近业余时间主要研究音视频开发这块,前面的文章写了好多种视频监控内核,一旦将这些内核搞定以后,视频监控的相关功能水到渠成。做视频监控系统,绕不过onvif这玩意,这玩意主要就是为了统一一个大概的标准,能够对各个厂家的监控设备进行常用的一些操作,比如搜索、获取信息、云台控制、事件订阅、抓拍图片等,如果没有这个规范,那么各个厂家都各自为政,需要用私有的sdk去处理,这样就很麻烦很惨了,几十个厂家就需要几十个sdk,对于程序员来说简直是灾难,想想就很恐怖的事情,哪个程序员不想多活几年!
feiyangqingyun
2020/10/04
1.1K0
Qt音视频开发27-Onvif设备搜索
Qt编写安防视频监控系统32-onvif信息获取
上一篇文章写的是onvif设备搜索,搜到这些设备以后,第一件事情就是要对设备信息获取一下,比如获取视频流地址,配置套件信息、码流信息、分辨率大小等,这些信息的获取根据具体的需要去获取,也没有必要全部获取,毕竟很可能大部分的信息用不到,按需编码永远都是第一原则,第二原则才是考虑拓展性和稳定性,如果基本的需求都实现不了,那就不是一个真正的软件,考虑再多的拓展性和稳定性都是白搭,说的严重一点就是:所有编程语言都是垃圾,能解决实际需求并变现才是王道!
feiyangqingyun
2020/08/02
1.1K0
Qt编写安防视频监控系统32-onvif信息获取
Qt音视频开发28-Onvif信息获取
严格意义上来说,Onvif处理这块算不上音视频开发的内容,为何重新整理放在音视频开发这个类别,主要是为了方便统一管理,而且在视频监控处理这块,通过onvif来拿到音视频流这是必经的阶段,也算是搭边的东西。上一篇文章写的是onvif设备搜索,搜到这些设备以后,第一件事情就是要对设备信息获取一下,比如获取视频流地址,配置套件信息、码流信息、分辨率大小等,这些信息的获取根据具体的需要去获取,也没有必要全部获取,毕竟很可能大部分的信息用不到,按需编码永远都是第一原则,第二原则才是考虑拓展性和稳定性,如果基本的需求都实现不了,那就不是一个真正的软件,考虑再多的拓展性和稳定性都是白搭,说的严重一点就是:所有编程语言都是垃圾,能解决实际需求并变现才是王道!
feiyangqingyun
2020/10/06
1.4K0
Qt音视频开发28-Onvif信息获取
Qt音视频开发34-Onvif时间设置
对设备设置时间很有必要,这个是必备的功能,毕竟大部分的前端设备比如摄像机本身不带BIOS电池的,所以没法存储时间,要么设置了NTP地址来同步时间,要么其他设备主动对他进行设置时间,如果时间不正确了,意味着本地画面显示的时间字符串,本地存储的视频录像文件等,都可能是不正确的,所以一般的处理是NVR一旦连上摄像机设备以后,立马将摄像机的时间设置成NVR的时间,这样就保持了一致。
feiyangqingyun
2020/10/14
1.2K0
Qt音视频开发34-Onvif时间设置
gsoap开发webservice
gSOAP编译工具提供了一个SOAP/XML 关于C/C++ 语言的实现,从而让C/C++语言开发web服务或客户端程序的工作变得轻松了很多。绝大多数的C++web服务工具包提供一组API函数类库来处理特定的SOAP数据结构,这样就使得用户必须改变程序结构来适应相关的类库。与之相反,gSOAP利用编译器技术提供了一组透明化的SOAP API,并将与开发无关的SOAP实现细节相关的内容对用户隐藏起来。 gSOAP的编译器能够自动的将用户定义的本地化的C或C++数据类型转变为符合XML语法的数据结构,反之亦然。
cloudskyme
2018/03/20
1.8K0
gsoap开发webservice
Qt音视频开发35-Onvif图片参数
视频中的图片的配置参数一般有亮度、饱和度、对比度、锐度等,以前一直以为这些需要通过厂家的私有协议SDK来设置才行,后面通过研究Onvif Device Manager 和 Onvif Device Test Tool 这两个onvif开发的必备工具以后,发现onvif协议也具备了修改 亮度、色彩度、饱和度这三个参数,当然这三个参数我见过的摄像机厂家(主流的十几种)都具备,还有些大厂做的设备还提供了其他详细图片参数的设置比如ICAT。
feiyangqingyun
2020/10/16
9400
Qt音视频开发35-Onvif图片参数
Qt音视频开发30-Onvif事件订阅
能够接收摄像机的报警事件,比如几乎所有的摄像机后面会增加报警输入输出接口,如果用户外接了报警输入,则当触发报警以后,对应的事件也会通过onvif传出去,这样就相当于兼容了所有onvif摄像机厂家的报警事件接收,在一些应用系统中,这个功能也是很常见的。接收摄像机的报警信息一般有两种处理方式,一种是订阅,订阅以后摄像机会在请求后一直阻塞等待,如果有新的报警信息则立即返回,否则需要到超时时间才会断开连接请求;还有一种是定时器主动轮询,不断的去询问是否有新的报警事件。关于订阅要阻塞等待的问题,这就涉及到另一个问题,一般Qt默认的并发请求最大6个(貌似这玩意好多浏览器也是这个规约,不知为何这么限定,为了节约系统资源?)这就意味着订阅机制下,最大只能有6个摄像机的报警事件订阅存在,超过就不行,除非有空闲的连接请求断开了,所以很多开发者会选择用其他的http post工具比如curl去处理。
feiyangqingyun
2020/10/09
1.1K0
Qt音视频开发30-Onvif事件订阅
python实现onvif协议-2
from suds.client import Client from suds.wsse import Security from suds_passworddigest.token import UsernameDigestToken url = 'file:///home/aphero/python/wsdl/media.wsdl' xadd='http://1.1.1.1/onvif/Media' client=Client(url,location=xadd) security = Security() token = UsernameDigestToken("admin", "12345") security.tokens.append(token) client.set_options(wsse=security) profiles=client.service.GetProfiles() for profile in profiles:     print profile._token,profile.Name     param={"StreamSetup":profile.Name,"ProfileToken":profile._token}     MediaUri=client.service.GetStreamUri(param)     print MediaUri.Uri
py3study
2020/01/03
1.8K1
Qt编写安防视频监控系统38-onvif校时
在视频监控系统中,对摄像机进行时间设置也是很有必要的,这样就和服务器或者软件这边统一了时间,一般在摄像机的画面上可以设置OSD标识当前时间,这样存储到视频文件中回放的时候,也能和本地的时间一致,一般的视频监控系统默认都会开启ONVIF校时,通过标准的公开的onvif协议来对前端摄像机设备进行时间设置,当然也可以获取时间。前端摄像机设备和后端管理软件或者服务器时间统一是非常重要的一个因素,本人经历过很多视频监控系统相关的项目,很多时候的报修情况就是因为前端设备时间和服务器端不一致的情况,导致的各种奇奇怪怪的问题。
feiyangqingyun
2021/07/01
1.1K0
Qt编写安防视频监控系统38-onvif校时
Onvif无法探测对应设备该如何处理?
从研发之初,EasyCVR安防协议视频综合管理系统就是作为一个“全能型”平台上线,支持各种私有协议接入的同时,也支持onvif探测。EasyCVR使用Onvif的优势就在终端用户和集成商可以使用不同制造商的技术及解决方案,该协议的支持给EasyCVR带来了更广泛的适用性。
TSINGSEE青犀视频
2021/03/16
1.1K0
Qt音视频开发32-Onvif网络设置
用onvif协议来对设备的网络信息进行获取和设置,这个操作在众多的NVR产品中,用的很少,绝大部分用户都还是习惯直接通过摄像机的web页面进去配置,其实修改网络配置的功能在大部分的NVR中都是具备的,网络的参数主要包括IP地址、子网掩码、网关地址、DNS解析地址、NTP地址、网卡信息、网络协议等,这些都可以通过不同的onvif命令来获取和设置,一直没有搞懂为啥这些要分开不同的命令去处理,其实大可以合并成一个命令嘛,搞得设置个网络信息还要post好多次的数据才行。
feiyangqingyun
2020/10/12
1.1K0
Qt音视频开发32-Onvif网络设置
gsoap入门:C/C++代码生成及编译
版权声明:本文为博主原创文章,转载请注明源地址。 https://blog.csdn.net/10km/article/details/52174616
10km
2019/05/25
3.7K0
Qt编写安防视频监控系统39-onvif图片参数
通过onvif来调整图片的Brightness(亮度)、ColorSaturation(色彩饱和度)、Contrast(饱和度)这三个参数,可以实时观测到监控画面对应的变化,比如讲亮度Brightness拉到最低,可以看到这个画面一片漆黑。通过onvif来调节图片的颜色光线,就无须通过厂家私有SDK去调节,当然厂家SDK能够去调节的参数肯定更多更全更好速度更快,这个功能用到的地方不多,大部分的时候其实还是安装调试期间,直接在前端摄像机的网页配置界面或者客户端界面上调整好,一般调整好以后基本上不会再去改动,尤其是经过验收的项目,经过专家的建议调整后固定在那个参数就行。
feiyangqingyun
2021/07/05
7950
Qt编写安防视频监控系统39-onvif图片参数
gsoap入门:获取服务器(axis2)端的异常(exception)对象
版权声明:本文为博主原创文章,转载请注明源地址。 https://blog.csdn.net/10km/article/details/52200348
10km
2019/05/25
7140
gsoap入门:解决axis2服务器返回错误
版权声明:本文为博主原创文章,转载请注明源地址。 https://blog.csdn.net/10km/article/details/52198306
10km
2019/05/25
1.6K0
Qt音视频开发31-Onvif抓拍图片
抓拍是个很重要的功能,比如在报警视频联动中需要一张实时的图片,很多SDK不提供抓拍功能,而通过预览抓图,得到的图片已不具有实时性,那如何得到实时的图片呢?现在的IPC基本上都支持ONVIF协议,ONVIF协议除了提供RTSP的URL外,其实也给出了抓拍的URL,从Media的GetSnapshotUri获取。
feiyangqingyun
2020/10/10
1.4K0
Qt音视频开发31-Onvif抓拍图片
onvif协议最新版本_接口协议测试工具
随着网络及软件技术快速发展,视频监控系统已经遍及于人们生活的每个角落,社会安全保障也得到了进一步的提升。随着视频监控系统的普及,视频监控的产业链也得到了空前的发展,产业链中的分工也越来越细。有些厂商专注于做监控摄像头,有些厂商专门做大屏显示器与拼接设备,有些厂商专门做DVR和NVR录像机,有些厂商则专注于做平台软件等,然后这些类别的产品通过集成商进行集成,给客户提供一整套完整的解决方案。
全栈程序员站长
2022/11/19
2.4K0
onvif协议最新版本_接口协议测试工具
Qt音视频开发29-Onvif云台控制
云台控制也是onvif功能中最常用的,最常用的功能排第一的是拿到视频流地址,排第二的就是云台控制了,云台控制的含义就是对带云台的摄像机进行上下左右的移动,一般云台摄像机都是带有一个小电机,一旦收到485或者网络来的正确的指令以后就触发单片机程序,然后单片机程序驱动电机进行转动,所以相对来说云台摄像机比普通的摄像机更耗电,当然价格也更贵。
feiyangqingyun
2020/10/08
1.2K0
Qt音视频开发29-Onvif云台控制
推荐阅读
相关推荐
Jetson Nano 使用gSOAP生成ONVIF框架代码及动态库 -- 3 ONVIF 动态库生成
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验