先看效果:
element-ui中的switch开关无loading属性(在element-plus时加入了),而且点击时开关状态就会切换,这使得在需要调用接口后再改变开关状态变得比较麻烦。
思路:switch开关外包一层div,给div添加click事件,emit给父组件,在父组件里进行开关状态的切换。
开关组件源码:
html
<template>
<div class="custom-switch" @click="switchClick">
<div style="width: fit-content;height: fit-content;" v-loading="loading">
<el-switch style="position: relative;" v-bind="$attrs"></el-switch>
</div>
</div>
</template>
<script>
/**
* el-switch开关组件二次封装
*
* description:
* 移除了el-switch的change事件
* 添加了loading效果
* 开关的value值交给父组件处理
*/
export default {
name: 'CustomSwitch',
props: {
loading: {
default: false,
type: Boolean
}
},
data() {
return {}
},
created() {},
mounted() {},
methods: {
switchClick() {
// 如果禁用和loading状态,不emit给父组件
if (this.$attrs.disabled || this.loading) {
return
}
this.$emit('switch-click', this.$attrs.value)
}
}
}
</script>
<style lang="scss" scoped>
.custom-switch {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
::v-deep .el-loading-mask {
width: 100%;
height: 100%;
border-radius: 10px;
top: 2px;
.el-loading-spinner {
position: relative;
width: 100%;
height: 100%;
top: unset;
margin-top: unset;
display: flex;
align-items: center;
justify-content: center;
svg {
width: 20px;
height: 20px;
}
}
}
}
</style>
父组件:
html
<template>
<custom-switch
v-model="switchValue"
:loading="switchLoading"
:active-value="1"
:inactive-value="0"
:disabled="switchDisabled"
@switch-click="switchClick"
/>
</template>
html
<script>
import CustomSwitch from './custom-switch.vue'
export default {
components: { CustomSwitch },
data() {
return {
switchValue: 1,
switchLoading: false,
switchDisabled: false
}
},
methods: {
switchClick() {
this.switchLoading = true
// 这里就可以调用接口,接口成功后修改值和loading状态
setTimeout(() => {
this.switchValue = !this.switchValue ? 1 : 0
this.switchLoading = false
}, 2000)
}
}
}
</script>