就是比如说:
有一个对象 a,他里面有个属性为 b(他是个对象);我们想操作 b 里面的属性,通常是这样的:
const a = { b: { name: 'bbb' }}// 操作 name 通常做法为a.b.name = 'xxx';// 如果事件代理是这样的a.name = 'xxx';这就是我们说的 事件代理;操作 比较方便;
我们在 vue 项目中,打印出 vm 实例,看看里面有什么:
Vue {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …} $attrs: Object $children: [] $createElement: ƒ (a, b, c, d) $el: div#app $listeners: (...) $options: {…} $parent: undefined $refs: {} $root: Vue {…} $scopedSlots: {} $slots: {} $vnode: undefined name: "xiaomin" _c: ƒ (a, b, c, d) _data: name: "xiaomin" __ob__: Observer {value: {…}, dep: Dep, vmCount: 1} get name: ƒ reactiveGetter() set name: ƒ reactiveSetter(newVal) __proto__: Object _directInactive: false _events: {}于是我们可以这样获取到 data 中的 name 属性:
const vm = new Vue({ el: '#app', data: { name: 'xiaomin' }})console.log(vm); // xiaominconsole.log(vm.name, vm._data.name); // xiaomin主要看看 name 和 _data 这2个属性;
为什么 vm 中会有原本在 data 里面的 name 属性呢?
这个涉及到 vue 的 事件代理;
我们使用 git 上别人模拟 vue 底层实现的方法,我们使用他的代码:git 地址
我们下载进行引入
文件结构:09.事件代理.htmllib mvvm.js complie.js observe.js watcher.js<html lang="en"><head> <meta charset="UTF-8"> <title>事件代理title>head><body> <div id="app"> div><script src="./bil/mvvm.js">script><script src="./bil/compile.js">script><script src="./bil/observer.js">script><script src="./bil/watcher.js">script><script> const vm = new MVVM({ el: '#app', data: { name: 'xiaomin' }}) console.log(vm); console.log(vm.name, vm._data.name);script>body>html>我们进行 Sources 调试:
打开控制台,选中 Sources 井点击 09.事件代理.html

调试有几个按钮,分别为 :

执行到下一个断点,如果没有就全部执行完毕;
执行完当前的代码段;比如整个函数;
进入;
出;
我们在 vm 实例处打断的,然后刷新页面,就可以开始进行调试了:
我们点击 进入 按钮,就进入到了 mvvm.js 文件了

然后我们点击 第二个按钮,执行当前的 代码段;就可以看到各代码的执行结果了:

然后我们可以对 执行过 的代码片段进行分析,看他们做了什么,存储了什么;
到了当前选中的这里, me._proxy 不知道是什么,我们可以选中他所在的这一行,如:

点击进入按钮,再点击,进入到 proxy() 这个方法;
我们可以看到跳到底部的 方法中:

我们可以看到 Object.definedProperty() 这个方法,给 me 就是 实例添加 data 中的 属性,并进行 监听 和 获取;这就是基本的 事件代理 的过程;
参考视频:
<a src="https://www.bilibili.com/video/BV1Wp411d7Ur?p=50">哔哩哔哩 尚硅谷 vue 视频a>