使用Puppeteer获取#app元素的__vue__属性返回undefined如何解决
问题排查与修复方案
核心原因:page.evaluate仅支持返回JSON可序列化的原始值,所有不可序列化的对象(DOM节点、Vue实例、含循环引用的对象、函数)都会被自动转为undefined,同时你当前的代码没有做页面加载状态校验,也用了不存在目标元素的测试地址。
具体修复步骤
- 替换测试地址,调整页面加载等待逻辑
示例中使用的Google站点本身不存在#app元素和__vue__属性,需要替换为你自己的Vue项目地址。同时增加页面加载等待配置,确保Vue实例完成挂载:
// 替换原goto逻辑 await page.goto('你的Vue项目实际访问地址', { waitUntil: 'networkidle2', // 等待网络空闲,保证JS执行完成 timeout: 30000 }) // 显式等待#app元素渲染完成 await page.waitForSelector('#app', { timeout: 10000 })- 替换测试地址,调整页面加载等待逻辑
- 提取可序列化字段返回
不要直接返回整个Vue实例或DOM元素,单独提取你需要的纯值类型字段:
const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); await page.goto('你的Vue项目实际访问地址', { waitUntil: 'networkidle2', timeout: 30000 }); await page.waitForSelector('#app', { timeout: 10000 }); const functionToInject = function(){ const appEl = document.querySelector('#app'); // 提前做判空,避免运行时报错 if (!appEl) return { error: '#app元素不存在' } if (!appEl.__vue__) return { error: 'Vue实例未挂载到#app' } const targetBase = appEl.__vue__.$root.$options._base; // 仅提取你需要的可序列化字段,不要直接返回整个targetBase return { // 示例提取字段,根据你的实际需求调整 constructorName: targetBase.name, prototypeKeys: Object.keys(targetBase.prototype), // 补充其他你需要的字符串、数字、布尔、普通对象类型字段 } } const data = await page.evaluate(functionToInject); console.log(data) await browser.close(); })();- 提取可序列化字段返回
- 若需要查看完整不可序列化属性,直接在浏览器上下文操作
如果你需要查看完整的__vue__属性结构,不需要把值传回Node.js,直接在注入函数内打印,监听页面控制台输出即可:
// 新增监听页面控制台事件 page.on('console', (msg) => { console.log('浏览器控制台输出:', msg.text()) }) // 注入函数内直接打印,不需要返回 await page.evaluate(() => { console.log(document.querySelector('#app').__vue__) })- 若需要查看完整不可序列化属性,直接在浏览器上下文操作
注意:Vue3的项目中不会在DOM节点上挂载__vue__属性,只有Vue2的项目支持该用法。
内容的提问来源于stack exchange,提问作者Владимир Владимирович
相关产品推荐
相关产品推荐

