封装单选框

<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'"
                            />

 

 

posted @ 2023-12-12 16:29  未几  阅读(11)  评论(0编辑  收藏  举报