先看效果:

element-ui中的switch开关无loading属性(在element-plus时加入了),而且点击时开关状态就会切换,这使得在需要调用接口后再改变开关状态变得比较麻烦。
思路:switch开关外包一层div,给div添加click事件,emit给父组件,在父组件里进行开关状态的切换。
开关组件源码:
- <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>
父组件:
- <template>
- <custom-switch
- v-model="switchValue"
- :loading="switchLoading"
- :active-value="1"
- :inactive-value="0"
- :disabled="switchDisabled"
- @switch-click="switchClick"
- />
- template>
- <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>