效果
<template>
<div class="toggle-button-wrapper">
<input type="checkbox" id="toggle-button" name="switch" :checked="checked" v-on="listeners" @change="onChange" />
<label for="toggle-button" class="button-label">
<span class="circle">{{ checked ? onText : offText }}</span>
</label>
</div>
</template>
<script>
export default {
name: 'Switch',
inheritAttrs: false,
props: {
onText: {
type: String,
default: '开启'
},
offText: {
type: String,
default: '关闭'
},
propsChecked: {
type: Boolean,
default: false
}
},
data() {
return {
checked: true
}
},
computed: {
listeners() {
let result = Object.assign({}, this.$listeners)
return result
}
},
methods: {
onChange(e) {
this.checked = e.target.checked
this.$emit('change', e.target.checked)
}
},
created() {
this.checked = this.propsChecked
}
}
</script>
<style lang="scss" scoped>
#toggle-button {
display: none;
}
.button-label {
position: relative;
display: inline-block;
width: 180px;
height: 60px;
background: #ffffff;
border: 0.9975px solid #e06565;
border-radius: 31.9999px;
box-sizing: border-box;
}
.circle {
position: absolute;
top: 0;
width: 120px;
height: 58.9999px;
border-radius: 31.9999px;
line-height: 60px;
text-align: center;
color: #fff;
transition: all 0.3s ease;
}
.button-label .circle {
left: -1px;
right: auto;
background: #fa607f;
box-shadow: 0 5px 15px rgba(250, 96, 127, 0.4);
}
#toggle-button:checked + label.button-label {
border: 0.9975px solid #5e6ffa;
font-size: 24px;
}
#toggle-button:checked + label.button-label .circle {
left: 60px;
right: -1px;
background: #5d75f7;
box-shadow: 0 5px 15px 0 rgba(94, 111, 250, 0.4);
}
</style>
样式二
<template>
<div class="toggle-button-wrapper">
<input type="checkbox" id="toggle-button" name="switch" :checked="checked" v-on="listeners" @change="onChange" />
<label for="toggle-button" class="button-label">
<div class="default">
<span>男孩</span>
<span>女孩</span>
</div>
<span class="circle">{{ checked ? onText : offText }}</span>
</label>
</div>
</template>
<script>
export default {
name: 'Switch',
inheritAttrs: false,
props: {
onText: {
type: String,
default: '女孩'
},
offText: {
type: String,
default: '男孩'
},
propsChecked: {
type: Boolean,
default: false
}
},
data() {
return {
checked: true
}
},
computed: {
listeners() {
let result = Object.assign({}, this.$listeners)
return result
}
},
methods: {
onChange(e) {
this.checked = e.target.checked
this.$emit('change', e.target.checked)
}
},
created() {
this.checked = this.propsChecked
}
}
</script>
<style lang="scss" scoped>
#toggle-button {
display: none;
}
.default {
display: flex;
justify-content: space-around;
align-items: center;
font-size: 24px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #8c8ea5;
line-height: 24px;
height: 52px;
}
.button-label {
position: relative;
display: inline-block;
box-sizing: border-box;
width: 160px;
height: 52px;
border-radius: 26px;
background: rgba(140, 142, 165, 0.1);
}
.circle {
position: absolute;
top: 0;
line-height: 52px;
text-align: center;
transition: all 0.3s ease;
font-size: 24px;
color: #fff;
width: 80px;
height: 52px;
background: #5867ff;
border-radius: 26px;
}
.button-label .circle {
left: -1px;
right: auto;
background: #5867ff;
color: #ffffff;
}
#toggle-button:checked + label.button-label {
}
#toggle-button:checked + label.button-label .circle {
left: 75px;
right: -1px;
background: #5d75f7;
}
</style>