如何用Greasemonkey修改第三方Vue.js应用的模板?
用Greasemonkey修改第三方Vue生产环境应用模板的解决方案
一、解决无法访问__vue__属性的问题
Greasemonkey脚本默认运行在沙箱环境,和页面全局上下文隔离,所以直接访问元素的__vue__会失败。有两种可行的解决方式:
1. 使用unsafeWindow访问页面上下文
通过@grant unsafeWindow声明权限后,直接调用页面环境的变量和方法:
// ==UserScript== // @name 获取Vue实例 // @match https://目标网站域名/* // @grant unsafeWindow // ==/UserScript== (function() { 'use strict'; // 等待Vue实例挂载完成,可根据页面加载速度调整延迟 setTimeout(() => { const vueElement = unsafeWindow.Array.from(document.querySelectorAll('*')).find(el => el.__vue__); if (vueElement) { const vueInstance = vueElement.__vue__; console.log('成功获取Vue实例:', vueInstance); // 后续模板修改操作放在这里 } }, 1500); })();
2. 注入脚本到页面上下文
创建并插入一个<script>标签,让脚本运行在页面自身的上下文里,直接访问__vue__:
// ==UserScript== // @name 注入脚本获取Vue实例 // @match https://目标网站域名/* // @grant none // ==/UserScript== (function() { 'use strict'; const injectScript = document.createElement('script'); injectScript.textContent = ` setTimeout(() => { const vueElement = Array.from(document.querySelectorAll('*')).find(el => el.__vue__); if (vueElement) { const vueInstance = vueElement.__vue__; console.log('成功获取Vue实例:', vueInstance); // 这里执行模板修改逻辑 } }, 1500); `; document.head.appendChild(injectScript); })();
二、修改运行中Vue应用的模板
生产环境下Vue会把模板编译成渲染函数,原始模板已不存在,但可以通过以下方式修改页面渲染结果:
1. 重写渲染函数
拿到Vue实例后,修改其$options.render方法,在原有渲染结果上添加或修改内容:
// 以下代码放在注入脚本或unsafeWindow的逻辑中 const originalRender = vueInstance.$options.render; vueInstance.$options.render = function(h) { const vnode = originalRender.call(this, h); // 示例:给根节点追加一个红色提示元素 vnode.children.push(h('div', { style: { color: '#ff0000', padding: '8px' } }, 'Greasemonkey添加的自定义内容')); return vnode; }; // 强制实例重新渲染 vueInstance.$forceUpdate();
2. 修改响应式数据(更稳定)
直接修改Vue实例的$data(或压缩后的对应属性,生产环境可能被混淆为_data),利用Vue的响应式特性自动更新DOM,避免直接操作DOM被覆盖:
// 假设实例中有`username`属性,修改它 vueInstance.$data.username = '修改后的用户名'; // 如果属性被混淆,先在控制台确认实际属性名,比如可能是`_data.a`
3. Vue 3的适配
Vue 3的实例结构不同,获取方式调整如下:
const vueElement = document.querySelector('[data-v-app]'); const vueInstance = vueElement.__vue_app__._instance; // 重写渲染函数的逻辑类似,Vue 3的渲染函数参数是`renderContext`,需要调整处理方式
三、注意事项
- 生产环境Vue代码通常会被压缩,变量名会被混淆,需要先在浏览器控制台确认实例的实际属性名。
- 不同网站的Vue版本(2/3)会影响操作逻辑,先通过
vueInstance.$vnode(Vue2)或vueInstance.type(Vue3)判断版本。 - 频繁修改渲染函数可能影响页面性能,尽量只做必要的修改。
- 部分网站可能有反篡改机制,需测试验证脚本有效性。
内容的提问来源于stack exchange,提问作者Stefan Krüger s-light
相关产品推荐
相关产品推荐

