可自定义设置以下属性:
初始是否选中(defaultChecked),默认 false
选择时的内容(checkedInfo),默认 null
未选中时的内容(uncheckedInfo),默认 null
是否禁用(disabled),默认 false
(v-model)指定当前是否选中(checked),默认 null
效果如下图:
①创建开关组件Switch.vue:
<template>
<div class="m-switch-wrap">
<div @click="disabled ? e => e.preventDefault() : onSwitch()" :class="['m-switch', { 'switch-checked': checkedVal, 'disabled': disabled }]">
<div :class="['u-switch-inner', checkedVal ? 'inner-checked' : 'inner-unchecked' ]">{
{ checkedVal ? checkedInfo : uncheckedInfo }}</div>
<div :class="['u-node', { 'node-checked': checkedVal }]"></div>
</div>
</div>
</template>
<script>
export default {
name: 'Switch',
model: {
prop: 'checked',
event: 'change'
},
props: {
defaultChecked: { // 初始是否选中
type: Boolean,
default: false
},
checkedInfo: { // 选中时的内容
type: [Number, String],
default: null
},
uncheckedInfo: { // 未选中时的内容
type: [Number, String],
default: null
},
disabled: { // 是否禁用
type: Boolean,
default: false
},
checked: { // (v-model)指定当前是否选中
type: Boolean,
default: null
}
},
data () {
return {
checkedVal: null
}
},
watch: {
checked () {
this.initSwitcher()
},
defaultChecked () {
this.initSwitcher()
}
},
created () {
this.initSwitcher()
},
methods: {
initSwitcher () {
if (typeof this.checked === 'boolean') {
this.checkedVal = this.checked
} else if (typeof this.checked === 'object') {
this.checkedVal = this.defaultChecked
}
},
onSwitch () {
this.checkedVal = !this.checkedVal
this.$emit('change', this.checkedVal)
}
}
}
</script>
<style lang="less" scoped>
@themeColor: #1890FF;
.m-switch-wrap {
height: 22px;
min-width: 44px;
display: inline-block;
.m-switch {
position: relative;
height: 22px;
color: rgba(0,0,0,.65);
font-size: 14px;
background: rgba(0,0,0,.25);
border-radius: 100px;
cursor: pointer;
transition: background .36s;
.u-switch-inner {
display: inline-block;
color: #fff;
font-size: 14px;
line-height: 22px;
padding: 0 8px;
transition: all .36s;
}
.inner-checked {
margin-right: 18px;
}
.inner-unchecked {
margin-left: 18px;
}
.u-node {
position: absolute;
top: 2px;
left: 2px;
width: 18px;
height: 18px;
background: #FFF;
border-radius: 100%;
cursor: pointer;
transition: all .36s;
}
.node-checked { // 结果等价于right: 2px; 为了滑动效果都以左边为基准进行偏移
left: 100%;
margin-left: -2px;
transform: translateX(-100%);
}
}
.switch-checked {
background: @themeColor;
}
.disabled {
cursor: not-allowed;
opacity: .4;
}
}
</style>
②在要使用的页面引入组件:
<Switch :defaultChecked="true" v-model="checked" checkedInfo="开" uncheckedInfo="关" :disabled="false" />
import Switch from '@/components/Switch'
export default {
name: 'Index',
components: {
Switch
},
data () {
return {
checked: true
}
}
}