之前看react能去除知乎div, 就想着vue应该也能有类似的玩法, 就试了一下... 讲道理, 这种做法应该是可以拿到更多东西的, 甚至可以获取表达输入, 原理就这样, 懒得继续搞了
效果如下
原理是通过vue暴露给cli工具的实例, 拿到原型链, 然后修改原型链上的方法
实现原理
代码比较简单, 核心检测代码来自vue cli 拿到Vue后, 修改原型链上的方法即可, 主要注意this的指向问题
const all = document.querySelectorAll("*")
let el
for (let i = 0; i < all.length; i++) {
if (all[i].__vue__) {
el = all[i]
break
}
}
let Vue
if (el) {
Vue = Object.getPrototypeOf(el.__vue__).constructor
while (Vue.super) {
Vue = Vue.super
}
}
const nuxtDetected = Boolean(window.__NUXT__ || window.$nuxt)
if (nuxtDetected) {
if (window.$nuxt) {
Vue = window.$nuxt.$root.constructor
}
}
const _render = Vue.prototype._render
function r(...args) {
const self = this
console.log("r", ...args, self)
console.log("el", self, self.$el)
// el的挂载是异步的, 直接获取是不可以的
// 用nextTick在渲染完毕后设置颜色
Vue.prototype.$nextTick(() => {
console.log("el2", self, self.$el)
if (self.$el && self.$el.style) {
self.$el.style.color = "red"
}
})
const _createElement = self.createElement
function c(...args) {
console.log("c", ...args)
// 这个函数暂时没有用到...
return _createElement(...args)
}
self.createElement = c
return _render.call(self, ...args)
}
Vue.prototype._render = r