通过劫持Proxy方法,逆向还原Vue3 app元素到DOM
This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.greasyfork.org/scripts/449444/1081400/Hook%20Vue3%20app.js
本脚本库作者完全没有接触过Vue2及Vue3正向开发,也不清楚其具体正向原理(脚本原理是倒推的)
本脚本库是作者根据自身JS经验及油猴中文网脚本开发指南加上断点逆向无意中发现的通用劫持方法而写,
局限于作者水平,可能存在诸多不合理之处,尽请谅解,另外欢迎交流、探讨。
根据Vue数据绑定机制,Vue为了保证数据同步,会对每个实例均创建一个app对象用于数据存储、监听、同步;
一旦该app对象中存储的变量发生变化,Vue便会监听到该变化并将其作用到相应的DOM元素中,以实现前端交互。
该app对象存在于闭包中,Vue2将其挂载在DOM元素中的__vue__
属性中,可令油猴脚本直接获取;
但Vue3并未提供该方法,这导致通常油猴脚本无法直接获取app对象,加大针对Vue3框架的油猴脚本的开发难度。
本脚本库根据Vue3的数据绑定原理,通过劫持Proxy方法以暴露Vue3 app对象,并将其还原挂载到DOM元素中,
进而使油猴脚本可直接访问、操作该app对象,以实现油猴脚本与Vue3的快速交互。
vueHooked
[object WeakMap] 以WeakMap存储已劫持的app对象,DOM元素为key,app对象为value
(同一个元素可能有多个app对象,以数组形式存储,下同)
vueUnhooked
[object WeakSet] 以WeakSet存储已获取到但未未劫持的app对象,作为debug用变量,正常情况WeakSet应为空
DOMelement.__vue__
[object Object] 已挂载到对应DOM元素属性的Vue app对象
(类似于Vue2的DOMelement.__vue__)
// @run-at document-start
// @require https://greasyfork.org/scripts/449444-hook-vue3-app/code/Hook%20Vue3%20app.js
// @run-at document-start
// @require https://scriptcat.org/lib/567/1.0.3/Hook%20Vue3%20app.js
// ==UserScript==
// @name Bilibile VUE3
// @run-at document-start
// @match https://www.bilibili.com/*
// @require https://greasyfork.org/scripts/449444-hook-vue3-app/code/Hook%20Vue3%20app.js
// @grant none
// ==/UserScript==
//暴露变量到全局
window._vueUnhooked_ = vueUnhooked;
window._vueHooked_ = vueHooked;
//等待元素加载
let timer = setInterval(() => {
let app = document.querySelector(".bili-video-card")
if (app?.__vue__) {
clearInterval(timer)
console.log("已加载元素", app)
}
})