最近在升级公司的老项目时遇到了点问题。那就是antd-vue
的弹框在关闭时,触发了两次回调,导致调了两次接口 。
vue版本:3.x,antdv版本:4.x。 公司的老项目是用的vue2.x和antdv1.x,升级时我基本是整个文件copy过来之后再改改。为什么可以这样做呢?原因就是:在vue3中是可以兼容vue2的选项式语法的。 回归标题提到的问题, 当我在子组件中使用a-modal时,当子组件以a-modal为根节点,就会出现这样的问题。 子组件代码如下:
vue
<template>
<a-modal v-model:open="visible" title="Modal Title" @cancel="cancel">
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</a-modal>
</template>
<script>
export default {
name: 'Npagination',
props: ['visibles'],
data() {
return {
}
},
methods: {
handleOpen() {
console.log('open from parent')
this.visible = true
},
cancel() {
this.visible = false,
this.$emit('cancel')
console.log('cancel from child')
}
},
computed: {
visible: {
get() {
return this.visibles
},
set(val) {
// this.$emit('update:visible', val)
}
}
},
components: {
}
}
</script>
<style></style>
父组件代码如下:
vue
<template>
<div>
<a-button type="primary" @click="visible2 = true">open v2 model</a-button>
<VModal :visibles="visible2" @cancel="handleCancel2" />
</div>
</template>
<script>
import VModal from '../modalTest/v2modal.vue'
export default {
name: 'Npagination',
data() {
return {
visible2:false
}
},
methods: {
handleCancel2(){
this.visible2 = false,
console.log('cancel from parent')
}
},
components: {
VModal
}
}
</script>
<style></style>
此时问题就出现了,首先看控制台,会发现警告:
这是因为a-model的oncancel上本应接收一个事件,而我们绑定了两个事件,所以它收到了一个数组类型的参数。那么此时点击弹框的取消按钮,会发生什么呢?
点击后我们看控制台:
cancel from parent
被打印了两次,这是为什么呢?因为子组件的根节点是a-modal
,因此父组件给子组件添加的cancel
事件在被子组件捕获的同时,也被子组件中的a-modal
组件捕获了,所以a-modal
共接收到两个cancel事件,引发了警告。当点击取消按钮后,总共触发了三次事件:
1.a-modal
组件的cancel
捕获到了父组件的cancel
,打印出了父组件中的cancel from parent
2.a-modal
组件的cancel
触发了了子组件的cancel
,打印出子组件的cancel from child
3.子组件将2中的事件抛给父组件,再次触发了父组件的cancel
,打印出了父组件的cancel from parent
解决办法:
1.在子组件的a-modal
外层套一个div
即可解决。 2.父组件给子组件绑定事件时,不要用cancel来绑定,换一个事件名称,如handleCancel
也可以避免这个问题
注意:上面阐述的是cancel事件相关的问题,事实上ok事件也是同理,开发时需要注意。