Hook Vue3 app

通过劫持Proxy方法,逆向还原Vue3 app元素到DOM

当前为 2022-08-12 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/449444/1080860/Hook%20Vue3%20app.js

  1. // ==UserScript==
  2. // @name Hook Vue3 app
  3. // @version 1.0.1
  4. // @description 通过劫持Proxy方法,逆向还原Vue3 app元素到DOM
  5. // @author DreamNya
  6. // @license MIT
  7. // @namespace https://gf.qytechs.cn/users/809466
  8. // ==/UserScript==
  9.  
  10. const $window = window.unsafeWindow || document.defaultView || window
  11. const realLog = $window.console.log; //反劫持console.log
  12. const realProxy = $window.Proxy; //劫持Proxy
  13.  
  14. var vueApp = {} //存储所有app
  15. var vueHooked = {} //存储已还原app
  16.  
  17. $window.Proxy = function () {
  18. let app = arguments[0]._
  19. if (app && app.uid >= 0) { //判断app
  20. let el = app.vnode.el
  21. if (el) {
  22. if (!el.__vue__) {
  23. el.__vue__ = app //存在el则还原__vue__
  24. if (el.__vue__) {
  25. recordVue(vueHooked, app)
  26. }
  27. }
  28. } else {
  29. //realLog(app,el)
  30. watchEl(app.vnode) //不存在el则进行观察
  31. }
  32. recordVue(vueApp, app)
  33. }
  34. return new realProxy(...arguments)
  35. }
  36.  
  37. function watchEl(vnode) { //观察el 变动时还原到DOM
  38. let value = vnode.el
  39. let hooked = false
  40. Object.defineProperty(vnode, "el", {
  41. get() {
  42. return value
  43. },
  44. set(newValue) {
  45. if (!hooked && this.el) {
  46. this.el.__vue__ = this.component
  47. if (this.el.__vue__) {
  48. hooked = true
  49. recordVue(vueHooked, this.component)
  50. //realLog(this.component,"已还原")
  51. }
  52. }
  53. value = newValue
  54. }
  55. })
  56. }
  57.  
  58. function recordVue(obj, app) { //以uid为key存储app
  59. if (!obj[app.uid]) { //uid不存在则直接存储
  60. obj[app.uid] = app
  61. } else if (Array.isArray(obj[app.uid])) {
  62. obj[app.uid].push(app)
  63. } else {
  64. obj[app.uid] = [obj[app.uid], app] //多个root相同uid时以数组形式存储 可能存在优化空间
  65. }
  66. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址