单选框到处可见,组件库不方便自定义样式,还是自己写吧。
效果图:
1、template部分
<template>
<label
class="v-radio flex"
:class="[{ disable: disabled }]"
:aria-disabled="disabled"
>
<span
class="v-radio_input flex"
:class="{
disable: disabled,
checked: model === label,
}"
>
<span class="v-radio_inner"></span>
<input
ref="radio"
class="v-radio_original"
:name="name"
:value="label"
v-model="model"
:disabled="disabled"
:aria-disabled="disabled"
@change="handleChange"
type="radio"
/>
</span>
<span>
<template v-if="!$slots.default">{{ label }}</template>
<slot></slot>
</span>
</label>
</template>
2、js部分
export default {
data() {
return {};
},
props: {
value: {},
label: {},
name: String,
disabled: {
type: Boolean,
default: false,
},
},
computed: {
model: {
get() {
return this.value;
},
set(val) {
this.$emit("input", val);
},
},
},
methods: {
handleChange() {
this.$nextTick(() => {
let defaultSlots = this.$slots.default[0];
let context = "";
if (defaultSlots.text) {
context = defaultSlots.text;
} else {
context = defaultSlots;
}
this.$emit("change", {
value: this.model,
label: this.label,
context,
});
});
},
},
};
3、css部分
点个赞嘛,不点赞的话打你哦!
.flex {
display: flex;
align-items: center;
}
.v-radio {
cursor: pointer;
margin-right: 28px;
&.disable {
color: #ccc;
cursor: not-allowed;
}
.v-radio_input {
position: relative;
border: 1px solid #ff5858;
border-radius: 50%;
margin-right: 8px;
transition: 0.3s;
&.disable {
border-color: #dad3d3;
}
&::before {
position: absolute;
top: 50%;
left: 50%;
content: "";
width: 8px;
height: 8px;
transform: translate(-50%, -50%);
border-radius: 50%;
background-color: #fff;
}
&.checked {
background: #ff5858;
}
.v-radio_inner {
width: 16px;
height: 16px;
border-radius: 50%;
}
.v-radio_original {
opacity: 0;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: -1;
}
}
}