>[success] # 移除$listeners -- 非兼容 ~~~ 1.$listeners 对象在 Vue 3 中已被移除。现在事件监听器是 $attrs 的一部分 ~~~ >[info] ## vue2.x 使用 ~~~ 1.'$listeners' 和'$attrs' 出发点的解决思路是一样的,前者是针对事件,后者是针对属性 ~~~ >[danger] ##### 案例说明 ~~~ 1.如果在父组件调用子组件的过程中事件配合'.native' 修饰符相当于给子组件加了一个事件,这样的好处 如果子组件内没有事件暴露出,但我们仅仅只是想通过操作子组件触发父组件的一些事,在通俗的理解 将子组件看做了一个普通dom 并且绑定了一个事件 2.先了解'v-on' 他是支持' v-on="{ mouseover: doTish, mouseout: doThat }"' 这种对象形式的使用 ~~~ >[danger] ##### 上面第一条的案例解释 ~~~ 1.下面案例如果事件没有使用'native'修饰符点击事件是不生效的,可以这么理解没有加是认为你在子组件 通过'$emit'将子组click事件暴露出来,加了理解成整体认为是一个dom元素仅仅是一个元素的click事件 2.子组件是由 'div' 嵌套 'button' 那通过'native'修饰的子组件被处罚事件属于div 还是属于button,这取决于 用户点击的位置,如果用户点击的位置是div 那么就是div触发的click事件 相反就是button触发 ~~~ * 父组件 ~~~ <template> <div> <my-button @click.native="onUseListener"></my-button> <!-- 不生效 --> <!-- <my-button @click="onUseListener"></my-button> --> </div> </template> <script> import myButton from '../components/MyButton' export default { name: 'testlison', components: { myButton }, methods: { onUseListener() { console.log(event.target) // 具体看你点的dom元素位置 } } } </script> <style scoped lang="less"></style> ~~~ * 子组件 ~~~ <template> <div> <button>ss</button> </div> </template> <script> export default { name: 'button' } </script> ~~~ >[danger] ##### $listeners 使用 ~~~ 1.下面课看出通过$listeners 在子组件在进行简写 ~~~ ~~~ <template> <div> <my-button @click="onUseListener" @mouseover='parentTest'></my-button> </div> </template> <script> import myButton from '../components/MyButton' export default { name: 'testlison', components: { myButton }, methods: { onUseListener() { console.log('onUseListener') // 具体看你点的dom元素位置 }, parentTest() { console.log('parentTest') } } } </script> <style scoped lang="less"></style> ~~~ * 没有使用 ~~~ <template> <div> <button @click='childrenClick' @mouseover='childrenTest'>ss</button> </div> </template> <script> export default { name: 'button', mounted() { console.log(this.$listeners) }, methods: { childrenClick() { this.$emit('click') }, childrenTest() { this.$emit('mouseover') } } } </script> ~~~ * 使用 ~~~ <template> <div> <button v-on='$listeners'>ss</button> </div> </template> <script> export default { name: 'button', mounted() { console.log(this.$listeners) // {click: ƒ, mouseover: ƒ} }, methods: { click() { this.$emit('click') }, test() { this.$emit('test') } } } </script> ~~~ >[danger] ##### 更多具体的参考这个 [跨层级](https://www.cnblogs.com/badaozongcai/articles/12791262.html) [利用计算属性合并](https://www.jumtu.com/article/116843.html) >[info] ## vue3.0 ?? 有点蒙蔽后续看 ~~~ 1.在 Vue 3 的虚拟 DOM 中,事件监听器现在只是以 on 为前缀的 attribute,这样就成了 $attrs 对象的一部分, 因此 $listeners 被移除了。 ~~~ >[danger] ##### 案例 ~~~ 1.如果是事件,在'$attrs' 对应的key 要加on 例如下面案例在'$attrs' 为 { onMouseover:fn..., onClick:fn..., } ~~~ ~~~ <template> <div> <my-button @click="onUseListener" @mouseover='parentTest'></my-button> </div> </template> <script> import myButton from '../components/MyButton' export default { name: 'testlison', components: { myButton }, methods: { onUseListener(val) { console.log('onUseListener') }, parentTest() { console.log('parentTest') } } } </script> <style scoped lang="less"></style> ~~~ ~~~ <template> <button v-bind="$attrs">ss</button> </template> <script> export default { inheritAttrs: false, mounted() { console.log(this.$attrs) } } </script> ~~~ >[danger] ##### vue3.x 移除.native ~~~ 1.移除后在以前使用.native 去掉即可 逻辑思维整体还是一样的 ~~~