在vue3中emit的使用方式与vue2有哪些区别?vue3中emit的正确姿势是什么?…
回顾vue2中的emit
在vue2中,子组件想要将自定义事件向上级透传的方式就是this.$emit(<changName>, payload)
child.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <template> <div> <button @click="onEmit"> 子组件透传事件 </button> </div> </template> <script> export default { methods: { onEmit() { this.$emit("on-change", "hi~"); } } } </script>
|
parent.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <template> <div> < child @on-change="onChildChange" /> </div> </template> <script> import Child from "./Child.vue"; export default { components: { Child }, methods: { onChildChange(v) { console.log(v); } } } </script>
|
以上就是vue2 中常见的emit使用方式。关键点就是子组件依赖this.$emit
透传,父组件使用子组件并v-on
指定子组件透传事件Name.
vue3的emit($emit, emits-options)
setup()中的$emit
在setup()的this 是不指向当前实例的(this为undefined),如果想使用使用$emit
的功能,需要借助setup(props, context)
中的context
;
context会暴露三个组件的property;
1 2 3 4 5 6 7 8 9 10 11 12
| export default { setup(props, context) { console.log(context.attrs)
console.log(context.slots)
console.log(context.emit) } }
|
在这里我们需要使用context.emit
;如下的🌰
child.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <template> <div> <button @click="clickBtn" class="btn-item">hi~</button> </div> </template> <script> import { defineComponent } from 'vue' export default defineComponent({ setup (props, ctx) { const clickBtn = () => { ctx.emit("on-change", "hi~"); }; return { clickBtn} } }) </script>
|
parent.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <template> <div> <emit-child @on-change="emitFn" /> </div> </template>
<script> import { defineComponent } from 'vue' import EmitChild from "./Child.vue" export default defineComponent({ components: { EmitChild }, setup () { const emitFn = v => { console.log(v); } return { emitFn } } }) </script>
|
效果图:
这里说一下如果触发的事件名与原生事件名同名(如 click)会出现问题: 自定义事件与原生事件都会触发
为此将代码略微修改后测试
1 2 3 4 5 6
| const clickBtn = () => { ctx.emit("click", "hi~"); };
<emit-child @click="emitFn" />
|
效果图
该问题如何解决呢?清往下看
emits-option
详细的文档说明,可以左转链接
在这里简单做一下总结
- emits是记录了当前组件的事件列表
- 类型: Array | Object
- 若为Object增加emit事件的校验(返回值应是
boolean
),
- 可以解决自定义事件名与原生事件相同导致事件多次执行问题(上述)
- emits无论是数组或者对象用法最终都会将事件给传递出去,数组或对象的使用只是为了记录实例中的emit事件,或者是验证事件中的参数