el-radio-group切换选项后按空格会不断触发input事件

1,116 阅读1分钟

今天遇到了一个奇怪的BUG,使用el-radio-group和el-radio组成单选框组时,切换选项后,如果连续按空格键,页面会不断刷新。

Snipaste_2024-07-16_10-29-24.png

(图中只展示精简之后的样子)

原代码

父组件


<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>

希望能给遇到同样问题的小伙伴提供一些思路