今天遇到了一个奇怪的BUG,使用el-radio-group和el-radio组成单选框组时,切换选项后,如果连续按空格键,页面会不断刷新。
(图中只展示精简之后的样子)
原代码
父组件
<template>
<div class="home">
<test :vRadio="vRadio" @changeRadio="changeRadio"/>
</div>
</template>
<script>
import test from '@/components/test.vue'
export default {
name: 'HomeView',
components: {
HelloWorld,
test
},
data(){
return{
vRadio:1
}
},
methods: {
changeRadio(value){
this.vRadio = value
console.log('选项',this.vRadio);
}
}
}
</script>
子组件
<template>
<div>
<el-radio-group v-model="radio" @input="change">
<el-radio :label="1">选项1</el-radio>
<el-radio :label="2">选项2</el-radio>
<el-radio :label="3">选项3</el-radio>
</el-radio-group>
</div>
</template>
<script>
export default {
props: {
vRadio: {
type: Number,
default: 1
}
},
data() {
return {
radio: this.vRadio
};
},
watch: {
vRadio(newVal) {
this.radio = newVal;
}
},
methods: {
change(e){
// console.log(e);
this.$emit('changeRadio',e)
}
}
}
</script>
解决方法
最后经过一番折腾,发现这个问题是由于 el-radio-group 和 el-radio 组件的默认行为与空格键交互导致的。空格键在单选按钮组中的默认行为是选择下一个单选按钮,因此会不断触发 input 事件。
以下是几个解决方法:
方法1:使用 change 事件
将 input 事件改为 change 事件。 change 事件只会在值实际变化时触发,而不是在每次按空格键时触发。
<template>
<div>
<el-radio-group v-model="radio" @change="input">
<el-radio :label="1">1</el-radio>
<el-radio :label="2">2</el-radio>
<el-radio :label="3">3</el-radio>
</el-radio-group>
</div>
</template>
方法2:自定义键盘事件
通过监听键盘事件并阻止空格键的默认行为来解决这个问题。
<template>
<div>
<el-radio-group v-model="radio" @change="input">
<el-radio :label="1">1</el-radio>
<el-radio :label="2">2</el-radio>
<el-radio :label="3">3</el-radio>
</el-radio-group>
</div>
</template>
<script>
export default {
props: {
vRadio: {
type: Number,
default: 1
}
},
data() {
return {
radio: 1
};
},
mounted() {
this.radio = this.vRadio;
window.addEventListener('keydown', this.handleKeydown);
},
beforeDestroy() {
window.removeEventListener('keydown', this.handleKeydown);
},
methods: {
input(e) {
console.log(e);
this.$emit('changeRadio', e);
},
handleKeydown(e) {
if (e.key === ' ') {
e.preventDefault();
}
}
}
}
</script>
方法3:禁用空格键在单选按钮中的作用
如果不希望空格键影响单选按钮,可以通过CSS禁用空格键在整个组件中的作用。
<template>
<div>
<el-radio-group v-model="radio" @change="input">
<el-radio :label="1">1</el-radio>
<el-radio :label="2">2</el-radio>
<el-radio :label="3">3</el-radio>
</el-radio-group>
</div>
</template>
<script>
export default {
props: {
vRadio: {
type: Number,
default: 1
}
},
data() {
return {
radio: 1
};
},
mounted() {
this.radio = this.vRadio;
},
methods: {
input(e) {
console.log(e);
this.$emit('changeRadio', e);
}
}
}
</script>
<style scoped>
.el-radio-group {
/* 禁用空格键在单选按钮中的作用 */
user-select: none;
}
</style>
希望能给遇到同样问题的小伙伴提供一些思路