上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
12下一页
返回列表 发新帖

[油猴脚本开发指南]监听Vue路由改变

[复制链接]
  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    637

    主题

    5196

    回帖

    6078

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6078

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2022-2-8 17:17:06 | 显示全部楼层 | 阅读模式

    前文

    本文按2022年2月8日16:58:21来看,如果你没有一定的逆向基础和框架源码的阅读基础,可能无法看懂,可以跳过本章继续向后学

    我们本节课目标监听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

    图片.png

    我们秒上去一个后置钩子

    router.afterEach((to, from) => {
      sendToAnalytics(to.fullPath)
    })

    我们观察vue-router源码

    https://github.com/vuejs/vue-router/blob/dev/dist/vue-router.js

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

    然后看registerHook

      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实例初始化的时候拿到的

    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));
            }
        }
      };

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

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

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

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

    vue-router源码在

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

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

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

    可以参考

    https://bbs.tampermonkey.net.cn/thread-1425-1-1.html

    https://bbs.tampermonkey.net.cn/thread-1438-1-1.html

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

    所以我们直接

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

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

    图片.png

    可以看到完成!

    结语

    世俗总要男人无惧无畏

    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
  • TA的每日心情
    开心
    4 小时前
  • 签到天数: 712 天

    [LV.9]以坛为家II

    27

    主题

    733

    回帖

    7219

    积分

    荣誉开发者

    精通各种语言的HelloWord!

    积分
    7219

    荣誉开发者油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2022-2-8 17:22:16 | 显示全部楼层
    世俗总要男人无惧无畏
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    637

    主题

    5196

    回帖

    6078

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6078

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2022-2-8 17:29:54 | 显示全部楼层
    Ne-21 发表于 2022-2-8 17:22
    世俗总要男人无惧无畏

    做人做事总是从容面对
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

    该用户从未签到

    0

    主题

    3

    回帖

    3

    积分

    助理工程师

    积分
    3
    发表于 2022-3-20 17:26:26 | 显示全部楼层
    帖主前端通吃啊,太强了
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    637

    主题

    5196

    回帖

    6078

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6078

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2022-3-20 17:42:04 | 显示全部楼层
    widcardw 发表于 2022-3-20 17:26
    帖主前端通吃啊,太强了

    说实话...
    我在论坛里算菜的
    被大哥们强行填鸭式学的vue源码
    我连vue3的组合式都写不好...
    被论坛大哥们跟幼儿园教小孩一样陪读vue源码读了半年多...
    导致我git不会用,css动画写不好,组合式不会,html标签都记不清几个
    他妈的设计原理倒是逼逼的一套一套的....
    比如一之,壮壮啥的
    都是一年底薪几十万的大哥....
    而我在家待业两年了


    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

    该用户从未签到

    0

    主题

    3

    回帖

    3

    积分

    助理工程师

    积分
    3
    发表于 2022-3-20 17:48:16 | 显示全部楼层
    李恒道 发表于 2022-3-20 17:42
    说实话...
    我在论坛里算菜的
    被大哥们强行填鸭式学的vue源码

    原来论坛里有不少 vue3 大佬啊,今后常来逛逛,刚从 vue2 的写法转向 vue3,不是很适应,尤其是 2021 年 7 月定稿的 setup script 标签语法糖,写起来很香,但是问题其实也不少。前两天看了阿崔(cxr)的视频,感觉自己会的东西还是太少了,要想将来能有什么好工作还必须要深入一些底层的东西吧。

    然后我看到 cxr 说如果直接去读 vue3 源码是直接会被劝退的,最好的方式还是先去了解一下它的核心,所以他开了一个仓库叫 mini-vue 来帮助初学者认识 vue3 的核心。

    于是我连这个 mini-vue 都看不懂
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    637

    主题

    5196

    回帖

    6078

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6078

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2022-3-20 17:56:19 | 显示全部楼层
    widcardw 发表于 2022-3-20 17:48
    原来论坛里有不少 vue3 大佬啊,今后常来逛逛,刚从 vue2 的写法转向 vue3,不是很适应,尤其是 2021 年  ...

    说实话...没必要
    学vue源码不如背题经
    了解一下响应式和dep依赖就得了
    学了感觉提升并不大...
    我学完全是为了写开发指南做底层注入的方案
    感觉平时写代码没啥变化

    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2023-11-2 17:37
  • 签到天数: 275 天

    [LV.8]以坛为家I

    114

    主题

    452

    回帖

    973

    积分

    荣誉开发者

    积分
    973

    荣誉开发者油中2周年卓越贡献生态建设者

    发表于 2022-6-27 08:46:34 | 显示全部楼层
    道哥yyds
    接脚本定制
    I frequently record, because want to leave something.
    回复

    使用道具 举报

    该用户从未签到

    0

    主题

    2

    回帖

    3

    积分

    助理工程师

    积分
    3
    发表于 2023-11-22 10:07:51 | 显示全部楼层
    特意注册一个账号给道哥点个赞
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    637

    主题

    5196

    回帖

    6078

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6078

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2023-11-22 15:20:28 | 显示全部楼层
    浪卷云 发表于 2023-11-22 10:07
    特意注册一个账号给道哥点个赞

    谢谢哥哥~
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

    发表回复

    本版积分规则

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