效果
业务组件
import BaseSwitch from '@/components/BaseSwitch/index.vue'
<BaseSwitch
:key="new Date()"
:switchValue="scope.status === 0"
@switch-click="witchChange(scope.status,scope)">
</BaseSwitch>
async function witchChange(val: IUserManagement.IUserPageApi['status'], scope: IUserManagement.IUserPageApi) {
const query = {
id: scope.id,
state: val === EnumUserStatus.Deactivate ? EnumUserStatus.Normal : EnumUserStatus.Deactivate,
}
await editUserStateApi(query) as any
reshCurrent()
}
封装
src\components\BaseSwitch\index.vue
<template>
<div
class="defineSwitch"
@click="handleSwitchClick">
<el-switch
:value="_switchValue"
:active-color="activeColor"
:inactive-color="inactiveColor"
:active-text="activeText"
:inactive-text="inactiveText"
:width="width"
>
</el-switch>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const props = defineProps({
width: {
type: Number,
default: 58,
},
activeText: {
type: String,
default: '启用',
},
inactiveText: {
type: String,
default: '停用',
},
activeColor: {
type: String,
default: '#1890FF',
},
inactiveColor: {
type: String,
default: '#979797',
},
switchValue: {
type: Boolean,
default: true,
},
})
const emits = defineEmits(['switch-click'])
const _switchValue = ref(props.switchValue)
/**
* 状态切换可能存在弹窗后,点击确定在进行下一步操作或者接口调用后再切换状态,
* 这里通知父组件已发生点击事件
*/
function handleSwitchClick() {
emits('switch-click', _switchValue.value)
}
/**
* 父组件业务完成后,通过ref手动改变状态
*/
function changeSwitchValue(val: boolean) {
_switchValue.value = val
}
defineExpose({
changeSwitchValue,
})
</script>
<style lang="scss">
.defineSwitch {
.el-switch__label * {
display: inline-block;
font-size: 12px;
line-height: 1;
}
.el-switch__label {
position: absolute;
display: none;
font-size: 12px !important;
color: #fff !important;
}
/* 打开时文字位置设置 */
.el-switch__label--right {
top: 0;
right: 24px;
z-index: 1;
}
/* 关闭时文字位置设置 */
.el-switch__label--left {
top: 0;
left: 24px;
z-index: 1;
}
/* 显示文字 */
.el-switch__label.is-active {
display: block;
}
/* 开关宽度 */
.el-switch__core,
.el-switch__label {
height: 22px;
}
.el-switch__core::after {
width: 18px;
height: 18px;
}
}
</style>