封装单选框
<template> <div class="radioButtons"> <label v-for="option in options" :class="{ 'is-selected': selectedValue === option.value }" :key="option.value" :for="option.value" > <input type="radio" :value="option.value" :id="option.value" :name="name" v-model="selectedValue" @change="handleChange" /> {{ option.label }} </label> </div> </template> <script> export default { name: 'RadioButtons', props: { name: { type: String, required: true }, options: { type: Array, required: true }, value: { type: String, default: '' } }, emits: ['update:value'], data() { return { selectedValue: this.value }; }, watch: { value(newValue) { this.selectedValue = newValue; }, selectedValue(newValue) { this.$emit('update:value', newValue); } }, methods: { handleChange(event) { this.$emit('change', event.target.value); } } }; </script> <style lang="scss" scoped> .radioButtons { label { position: relative; display: inline-block; padding: 10px 20px; margin: 0 10px 0 0; border: 2px solid #ddd; border-radius: 4px; cursor: pointer; transition: all 0.3s ease; } .is-selected { border-color: red; color: red; &::after { content: ''; position: absolute; width: 0; height: 0; border-left: 22px solid transparent; border-right: 0 solid; border-bottom: 22px solid red; right: 0; bottom: 0; } &::before { content: ''; position: absolute; right: 2px; bottom: 3px; z-index: 100; width: 3px; height: 7px; border-color: #fff; border-style: solid; border-width: 0 2px 2px 0; transform: rotate(45deg); } } input[type='radio'] { display: none; } } </style> <!-- <style lang="scss" scoped> .radioButtons { input[type='radio'] { display: none; } input[type='radio'] + label { position: relative; display: inline-block; padding: 10px 20px; margin: 0 10px 0 0; border: 2px solid #ddd; border-radius: 4px; cursor: pointer; transition: all 0.3s ease; } input[type='radio']:checked + label { border-color: red; color: red; } input[type='radio']:checked + label::after { content: ''; position: absolute; width: 0; height: 0; border-left: 22px solid transparent; border-right: 0 solid; border-bottom: 22px solid red; right: 0; bottom: 0; } input[type='radio']:checked + label::before { content: ''; position: absolute; right: 2px; bottom: 3px; z-index: 100; width: 3px; height: 7px; border-color: #fff; border-style: solid; border-width: 0 2px 2px 0; transform: rotate(45deg); } } </style> -->
使用
<RadioButtons
name="group1"
:options="radioOptions"
v-model="selectedRadio"
/>
selectedRadio: '',
radioOptions: [{ label: 'name', value: '1' }, { label: 'Option 2', value: 'option2' }],
优化后 可以根据是 传入宽高还是默认padding
<template>
<div class="radioButtons">
<label
v-for="option in options"
:class="getClass(option)"
:key="option.value"
:for="option.value"
:style="{ width: customWidth, height: customHeight }"
>
<input
type="radio"
:value="option.value"
:id="option.value"
:name="name"
v-model="selectedValue"
@change="handleChange"
/>
{{ option.label }}
</label>
</div>
</template>
<script>
export default {
name: 'RadioButtons',
props: {
name: {
type: String,
required: true
},
options: {
type: Array,
required: true
},
value: {
type: String,
default: ''
},
width: {
type: String,
default: 'auto'
},
height: {
type: String,
default: 'auto'
}
},
emits: ['update:value'],
data() {
return {};
},
computed: {
customWidth() {
return this.width !== 'auto' ? this.width : '';
},
customHeight() {
return this.height !== 'auto' ? this.height : '';
},
selectedValue: {
get() {
return this.value;
},
set(val) {
this.$emit('update:value', val);
}
}
},
methods: {
getClass(option) {
return {
'is-selected': this.selectedValue === option.value,
afferent: this.customWidth && this.customHeight
};
},
handleChange(event) {
this.$emit('change', event.target.value);
}
}
};
</script>
<style lang="scss" scoped>
.radioButtons {
label {
position: relative;
display: inline-block;
padding: 6px 20px;
margin: 0 10px 0 0;
border: 1px solid #dee5ed;
border-radius: 7px;
cursor: pointer;
transition: all 0.3s ease;
color: '#243045';
overflow: hidden;
}
.afferent {
position: relative;
margin: 0 10px 0 0;
padding: 0;
border: 1px solid #dee5ed;
border-radius: 7px;
cursor: pointer;
transition: all 0.3s ease;
color: '#243045';
display: inline-flex;
justify-content: center;
align-items: center;
}
.is-selected {
border-color: #ea281e;
color: #ea281e;
&::after {
content: '';
position: absolute;
width: 0;
height: 0;
border-left: 22px solid transparent;
border-right: 0 solid;
border-bottom: 22px solid #ea281e;
right: 0;
bottom: 0;
}
&::before {
content: '';
position: absolute;
right: 3px;
bottom: 3px;
z-index: 100;
width: 3px;
height: 7px;
border-color: #fff;
border-style: solid;
border-width: 0 2px 2px 0;
transform: rotate(45deg);
}
}
input[type='radio'] {
display: none;
}
}
</style>
使用
<RadioButtons name="group1" :options="radioOptions" v-model="selectedRadio" :width="'112px'" :height="'36px'" />