吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3576|回复: 12
收起左侧

[其他转载] [油猴脚本开发]监听Vue路由改变

  [复制链接]
李恒道 发表于 2022-4-22 00:54
本帖最后由 李恒道 于 2022-4-22 09:33 编辑

前文
我们本节课目标监听vue的路由跳转改变,地址是

https://www.bilibili.com/video/BV16z4y1o7Mr/?spm_id_from=333.788.recommend_more_video.1
Vue路由分类

古早的前端是直接跳转页面,由后端进行返回

而今晚【强行造词】的前端是在前端来控制路由的跳转,仅由后端在第一次访问的时候返回页面

之后的路由跳转全部托付给了浏览器

Vue的路由是由Vue-router来进行控制的

分为三种

history、hash、abstract模式

history就像

https://www.bilibili.com/video/BV16z4y1o7Mr/?spm_id_from=333.788.recommend_more_video.1

这种,是不带用#符号的,叫历史路由

而如果是hash模式,是带有#符号的

地址如http://localhost:8082/#/

而abstract模式普通开发还不怎么常用,以后我们再跟大家聊
问题

问题来了,我们如果想监听地址的改变,到底应该怎么做呢?

目前来说有两种方法,第一种就是根据hash模式以及history模式的路由跳转进行相应的监听

如history本质上是使用history的pushstate来进行地址跳转的

我们可以参考mdn

https://developer.mozilla.org/en-US/docs/Web/API/History/pushState

这样修改的地址只是显示在浏览器和历史记录中,并不会影响页面刷新

而hash的路由改变主要是通过addeventlistener对popstate或者hashchange进行监听来达到的

因为对其进行监听还是很简单,我们牛逼闲着蛋疼,所以我们主要玩注入!

首先观察vue-router官方手册

https://router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E5%85%A8%E5%B1%80%E8%A7%A3%E6%9E%90%E5%AE%88%E5%8D%AB


170903b1cc7fpfsppq1fa3.png
我们秒上去一个后置钩子
[JavaScript] 纯文本查看 复制代码
 
router.afterEach((to, from) => {
  sendToAnalytics(to.fullPath)
})

我们观察vue-router源码

https://github.com/vuejs/vue-router/blob/dev/dist/vue-router.js
[JavaScript] 纯文本查看 复制代码
 

VueRouter.prototype.afterEach = function afterEach (fn) {    return registerHook(this.afterHooks, fn)
  };


然后看registerHook
[JavaScript] 纯文本查看 复制代码
 
  function registerHook (list, fn) {
    list.push(fn);
    return function () {
      var i = list.indexOf(fn);
      if (i > -1) { list.splice(i, 1); }
    }
  }

大概阅读一下,可以看到是对list插入一个号桉树

而afterEach插入的是afterHooks数组

我们搜索afterHook数组

翻阅源代码,找到是在vue-router实例初始化的时候拿到的

[JavaScript] 纯文本查看 复制代码
var VueRouter = function VueRouter (options) {    if ( options === void 0 ) options = {};

    {
      warn(this instanceof VueRouter, "Router must be called with the new operator.");
    }
    this.app = null;
    this.apps = [];
    this.options = options;
    this.beforeHooks = [];
    this.resolveHooks = [];
    this.afterHooks = [];
    this.matcher = createMatcher(options.routes || [], this);

    var mode = options.mode || 'hash';
    this.fallback =
      mode === 'history' && !supportsPushState && options.fallback !== false;
    if (this.fallback) {
      mode = 'hash';
    }
    if (!inBrowser) {
      mode = 'abstract';
    }
    this.mode = mode;

    switch (mode) {
      case 'history':
        this.history = new HTML5History(this, options.base);
        break
      case 'hash':
        this.history = new HashHistory(this, options.base, this.fallback);
        break
      case 'abstract':
        this.history = new AbstractHistory(this, options.base);
        break
      default:
        {
          assert(false, ("invalid mode: " + mode));
        }
    }
  };

我们可以找到下方代码的最后一行有

[JavaScript] 纯文本查看 复制代码
    

   this.app = null;    this.apps = [];
    this.options = options;
    this.beforeHooks = [];
    this.resolveHooks = [];
    this.afterHooks = [];

那我们的目标非常简单,找到vue-router实例,对其afterHook投入一个函数,目标就搞定了,那我们该怎么找到vue-router实例呢

这里可能需要大量的学习,所以这里我直接给出答案了

vue-router源码在

[JavaScript] 纯文本查看 复制代码
  

  Object.defineProperty(Vue.prototype, '$router', {    get: function get () { return this._routerRoot._router }
  });

对vue的原型定义了一个$router,返回了vue-router实例,任何的vue实例都可以访问这个对象

那我们该怎么拿到vue实例呢?通过__vue__

一般页面的#app是一个根路径,通常存在__vue__属性

所以我们直接

document.querySelector('#app').__vue__.$router.afterHooks.push(()=>{console.log('路由发生改变')})

通过vue拿到vue实例,通过$router拿到vue路由对象,然后找到全局后置路由钩子,投入一个函数来进行监听

171649ktmfnntf6mhlivvm.png

可以看到完成!
结语

世俗总要男人无惧无畏

免费评分

参与人数 6吾爱币 +11 热心值 +5 收起 理由
goudanbuhaochi + 1 + 1 用心讨论,共获提升!
iLouis + 1 + 1 我很赞同!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
WX4885 + 1 + 1 ggnb!!!
逝去的初夏c + 1 道恒哥哥nb
夫子点灯 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Hmily 发表于 2022-4-22 01:39
李恒道 发表于 2022-4-22 00:59
为啥代码贴上去都乱了...

因为你混用导致的,既然用markdown就全用,别插discuz的代码了。
 楼主| 李恒道 发表于 2022-4-22 09:35
Hmily 发表于 2022-4-22 01:39
因为你混用导致的,既然用markdown就全用,别插discuz的代码了。

okk
修改了,老大
 楼主| 李恒道 发表于 2022-4-22 00:59
为啥代码贴上去都乱了...

点评

因为你混用导致的,既然用markdown就全用,别插discuz的代码了。  详情 回复 发表于 2022-4-22 01:39
xytwlh 发表于 2022-4-22 06:39
看看怎么样
sltgz 发表于 2022-4-22 06:51

感谢分享
bj9ye666 发表于 2022-4-22 07:13
感谢分享,又学习到了新玩法
头像被屏蔽
daisypojie 发表于 2022-4-22 08:38
提示: 作者被禁止或删除 内容自动屏蔽
cuixh11 发表于 2022-4-22 08:42


感谢分享
头像被屏蔽
NJSYDG 发表于 2022-4-22 08:43
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 01:40

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表