Vue 实现 Radio 按钮
在 Vue 中实现 Radio 按钮可以通过 v-model 绑定数据,结合 <input type="radio"> 和 <label> 实现交互。以下是具体实现方法:
基础实现
通过 v-model 绑定同一个变量,确保单选效果:

<template>
<div>
<input type="radio" id="option1" value="option1" v-model="selectedOption">
<label for="option1">选项1</label>
<input type="radio" id="option2" value="option2" v-model="selectedOption">
<label for="option2">选项2</label>
<p>当前选择: {{ selectedOption }}</p>
</div>
</template>
<script>
export default {
data() {
return {
selectedOption: ''
}
}
}
</script>
动态渲染选项
通过 v-for 动态生成 Radio 按钮组:
<template>
<div>
<div v-for="option in options" :key="option.value">
<input
type="radio"
:id="option.value"
:value="option.value"
v-model="selectedOption"
>
<label :for="option.value">{{ option.label }}</label>
</div>
<p>当前选择: {{ selectedOption }}</p>
</div>
</template>
<script>
export default {
data() {
return {
selectedOption: '',
options: [
{ value: 'opt1', label: '选项A' },
{ value: 'opt2', label: '选项B' },
{ value: 'opt3', label: '选项C' }
]
}
}
}
</script>
自定义样式
通过隐藏原生 <input> 并自定义 <label> 样式实现美化:

<template>
<div class="radio-group">
<div v-for="option in options" :key="option.value" class="radio-item">
<input
type="radio"
:id="option.value"
:value="option.value"
v-model="selectedOption"
class="radio-input"
>
<label :for="option.value" class="radio-label">
{{ option.label }}
</label>
</div>
</div>
</template>
<style>
.radio-input {
position: absolute;
opacity: 0;
}
.radio-label {
display: inline-block;
padding: 8px 16px;
border: 1px solid #ccc;
border-radius: 4px;
cursor: pointer;
}
.radio-input:checked + .radio-label {
background-color: #42b983;
color: white;
border-color: #42b983;
}
</style>
组件化封装
将 Radio 组封装为可复用的组件:
<!-- RadioGroup.vue -->
<template>
<div class="radio-group">
<div
v-for="option in options"
:key="option.value"
class="radio-item"
@click="selectOption(option.value)"
>
<input
type="radio"
:id="`${name}-${option.value}`"
:value="option.value"
v-model="internalValue"
class="radio-input"
>
<label :for="`${name}-${option.value}`" class="radio-label">
{{ option.label }}
</label>
</div>
</div>
</template>
<script>
export default {
props: {
value: { type: [String, Number], default: '' },
options: { type: Array, required: true },
name: { type: String, required: true }
},
computed: {
internalValue: {
get() { return this.value },
set(val) { this.$emit('input', val) }
}
},
methods: {
selectOption(val) {
this.internalValue = val
}
}
}
</script>
使用方法:
<template>
<RadioGroup
v-model="selectedOption"
:options="[
{ value: 'a', label: 'Alpha' },
{ value: 'b', label: 'Beta' }
]"
name="demo"
/>
</template>
<script>
import RadioGroup from './RadioGroup.vue'
export default {
components: { RadioGroup },
data() {
return {
selectedOption: 'a'
}
}
}
</script>
注意事项
- 同一组的 Radio 必须绑定相同的
v-model 变量
- 动态生成的 Radio 需要确保每个
id 唯一
- 使用组件时通过
v-model 实现双向绑定
- 移动端可增加触摸反馈效果提升体验