关于 Vue 自定义按钮组件 $emit(‘click‘) 一次触发两次的问题总结
子组件<template><button :class="['yt-button', ClassOfType, ClassOfSize]" @click="$emit('click')"><slot></slot></button></template><script>export default {name: "
子组件
<template>
<button :class="['yt-button', ClassOfType, ClassOfSize]" @click="$emit('click')">
<slot></slot>
</button>
</template>
<script>
export default {
name: "YtButton",
props: {
type: {
type: 'default' | 'primary' | 'success' | 'info' | 'warning' | 'danger' | 'text',
default: ''
},
size: {
type: 'default' | 'medium' | 'small' | 'mini',
default: ''
}
},
computed: {
ClassOfType() {
const { type } = this
return !type ? '' : `yt-button--${ type }`
},
ClassOfSize() {
const { size } = this
return !size ? '' : `yt-button--${ size }`
}
},
methods: {}
}
</script>
父组件引用
<template>
<div class="parent-container">
<yt-button size="small" type="success" @click="handleClick">测试</yt-button>
</div>
</template>
<script>
export default {
name: "Parent",
methods: {
handleClick(e) {
console.log('click', e)
}
}
}
</script>
最近,因为发现原有项目在浏览器中,初次加载的时候,会有较长的延迟。在谷歌评分系统中,经过检测,发现了问题在于开发时引用了 Element-Plus 作为 UI 组件库,而 EP 库本身的体量较为庞大,在整个页面初次加载的时候,加载的文件大小和占时达到了整体大小 58% 以上。
由此,决定在部分页面中,一些相对简单或使用功能并不多的组件剔除掉,以达到项目减负的目的。
在写自定义组件以及引用时,遇到了一个问题,也就是子组件中明明只做了一次 click 的 $emit 操作,却在父组件中触发了两次事件函数。
之后,在网上找了很多方案。
有提及通过 .stop 阻止事件冒泡的方案,但通过多次测试,并没有实质效果。
也有一个是通过 .once 的方案,但是很显然,这个方案并不符合需求。这个方案会使得按钮组件变成一次性触发,不可重复操作。
之后,又找到了一个“曲线救国”的方案,也就是通过 setTimeout 的方式,让同一个事件函数在一定时间内只能被触发一次,避免二次触发。虽然,这个方案,确实解决了问题,但却在复用性上存在极大的问题,尤其是修改原有引用的源码时,需要没处都添加上 setTimeout。所以,这也是不太合理的。
随后,想到了这个问题的根本原因,并不是 $emit 本身的问题,或者说,两次触发 handleClick 函数的,其实是两个地方,而不是都源自于子组件的 $emit 行为。
实际上,第一次触发 handleClick 函数的,确系子组件通过 $emit 提交的 click 事件。而另外的一次触发,则是父组件中,作为一个自定义标签元素的 <yt-button> 本身。
所以,要避免一次点击,两次触发 handleClick 函数,最简单的方式,就是在子组件中,把 $emit('click') 的行为去除掉。因为 click 事件,事实上在父级处就已经做了处理,并不需要在子组件中做新的处理。
更多推荐
所有评论(0)