李恒道 发表于 2024-11-15 10:12:44

【油猴开发指南】Vue2如何控制实例的原生事件周期

之前我们已经知道了Vue2在update函数中会对dom进行赋值` vm.$el.__vue__ = vm;`
如果想要得到Vue的组件事件该怎么做?
可以写一个简单的demo
```js
<template>
<div id="app">
    <button @click="inc=inc+1">{{ inc }}</button>
</div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
name: 'App',
data(){
    return {
      inc:0
    }
},
updated(){
    console.log('123')
}
}
</script>
```
在触发打印的位置下一个断点
堆栈如下
!(data/attachment/forum/202411/15/100939njz3j1yjh3nvrjrr.png)
其中第一个函数是我们自己的函数,第二个是为了捕获用户函数错误从而进行包装的函数,第三层函数应该就是我们需要的了,追进去看看
```js
function callHook$1(vm, hook, args, setContext) {
    if (setContext === void 0) {
      setContext = true;
    }
    // #7573 disable dep collection when invoking lifecycle hooks
    pushTarget();
    var prevInst = currentInstance;
    var prevScope = getCurrentScope();
    setContext && setCurrentInstance(vm);
    var handlers = vm.$options;
    var info = "".concat(hook, " hook");
    if (handlers) {
      for (var i = 0, j = handlers.length; i < j; i++) {
            invokeWithErrorHandling(handlers, vm, args || null, vm, info);
      }
    }
    if (vm._hasHookEvent) {
      vm.$emit('hook:' + hook);
    }
    if (setContext) {
      setCurrentInstance(prevInst);
      prevScope && prevScope.on();
    }
    popTarget();
}
```
我们可以发现组件的事件钩子都是从实例的$options通过对应的事件名进行获取
所以我们也可以相应的进行读取,插入,劫持等等操作,例如
```js
dom.__vue__.$options['updated'].push(()=>console.log('inject'))
```

李恒道 发表于 2024-11-15 13:28:28

回复测试

王一之 发表于 2024-11-15 14:09:09

ggnb

krystal 发表于 2024-11-15 17:12:05

又看到哥哥更新vue系列了ggnb!

李恒道 发表于 2024-11-15 20:06:17

krystal 发表于 2024-11-15 17:12
又看到哥哥更新vue系列了ggnb!

hhh
碰到有人vue有点问题就更点
一个人解决完了其他人就不用思考了

steven026 发表于 2024-11-16 05:53:43

GGNB 思路一下子打开了

whitesev 发表于 2024-11-17 13:26:46

GGNB :)
页: [1]
查看完整版本: 【油猴开发指南】Vue2如何控制实例的原生事件周期