vue radio组件实现
Vue Radio 组件实现方法
基础实现
使用 v-model 绑定单选按钮的值,确保同一组 radio 的 name 属性相同:
<template>
<div>
<input type="radio" id="option1" value="1" v-model="selected" name="group" />
<label for="option1">Option 1</label>
<input type="radio" id="option2" value="2" v-model="selected" name="group" />
<label for="option2">Option 2</label>
</div>
</template>
<script>
export default {
data() {
return {
selected: ''
}
}
}
</script>
动态渲染选项
通过 v-for 动态生成 radio 选项:
<template>
<div v-for="option in options" :key="option.value">
<input
type="radio"
:id="option.value"
:value="option.value"
v-model="selected"
name="dynamicGroup"
/>
<label :for="option.value">{{ option.label }}</label>
</div>
</template>
<script>
export default {
data() {
return {
selected: '',
options: [
{ value: 'a', label: 'Alpha' },
{ value: 'b', label: 'Beta' }
]
}
}
}
</script>
组件化封装
创建可复用的 Radio 组件:
<!-- RadioGroup.vue -->
<template>
<div class="radio-group">
<div
v-for="option in options"
:key="option.value"
class="radio-option"
@click="selectOption(option.value)"
>
<input
type="radio"
:id="`${name}-${option.value}`"
:value="option.value"
v-model="modelValue"
:name="name"
/>
<label :for="`${name}-${option.value}`">{{ option.label }}</label>
</div>
</div>
</template>
<script>
export default {
props: {
options: Array,
modelValue: [String, Number],
name: String
},
methods: {
selectOption(value) {
this.$emit('update:modelValue', value)
}
}
}
</script>
<style scoped>
.radio-option {
cursor: pointer;
margin: 5px 0;
}
</style>
使用自定义组件
在父组件中使用封装好的 Radio 组件:
<template>
<RadioGroup
v-model="selectedFruit"
:options="fruitOptions"
name="fruitSelection"
/>
</template>
<script>
import RadioGroup from './RadioGroup.vue'
export default {
components: { RadioGroup },
data() {
return {
selectedFruit: '',
fruitOptions: [
{ value: 'apple', label: 'Apple' },
{ value: 'banana', label: 'Banana' }
]
}
}
}
</script>
样式优化技巧
使用 CSS 隐藏原生 radio 并自定义样式:
<template>
<div class="custom-radio">
<input
type="radio"
:id="id"
:value="value"
v-model="modelValue"
class="radio-input"
/>
<label :for="id" class="radio-label">
<span class="radio-custom"></span>
{{ label }}
</label>
</div>
</template>
<style scoped>
.radio-input {
position: absolute;
opacity: 0;
}
.radio-label {
display: flex;
align-items: center;
cursor: pointer;
}
.radio-custom {
width: 20px;
height: 20px;
border: 2px solid #ddd;
border-radius: 50%;
margin-right: 10px;
position: relative;
}
.radio-input:checked + .radio-label .radio-custom {
border-color: #42b983;
}
.radio-input:checked + .radio-label .radio-custom::after {
content: '';
position: absolute;
width: 12px;
height: 12px;
background: #42b983;
border-radius: 50%;
top: 2px;
left: 2px;
}
</style>
表单验证集成
结合 Vuelidate 进行表单验证:

<template>
<div>
<div v-for="option in options" :key="option.value">
<input
type="radio"
:id="option.value"
:value="option.value"
v-model="selected"
@blur="$v.selected.$touch()"
/>
<label :for="option.value">{{ option.label }}</label>
</div>
<span v-if="$v.selected.$error" class="error">必须选择一个选项</span>
</div>
</template>
<script>
import { required } from 'vuelidate/lib/validators'
export default {
data() {
return {
selected: '',
options: [
{ value: 'yes', label: 'Yes' },
{ value: 'no', label: 'No' }
]
}
},
validations: {
selected: { required }
}
}
</script>






