前言:

最近开发新项目,CURD 写完了,接下来要写一个状态开关,可真是把 DD 难住了~

需求说明:

1、是根据后台返回 0(停用)1(启用) 动态显示开关

2、对开关进行操作时请求后台,需要传两个参数:idstatus

3、启用时传 1 停用时传 0 并携带 id ,当主机下面包含通道时则不能改变状态,并根据 msg 给出提示

想都没想就打算按照以前老项目思路来,大概长这样

乍一看也能用,就是不炫,而且实现的代码也不优雅,后来在 element-ui 官网看到 Switch 开关 这个组件,这不正是我想要的吗

Switch 开关

兴高采烈的 Ctrl+c Ctrl+v emmmm….

<el-table-column
    prop="status"
      label="状态" 
      align='center'
      width="150">
    <template slot-scope='scope'>
        <el-switch v-model="scope.row.status"
             active-value="1"
             inactive-value="0">
        </el-switch>
     </template>
</el-table-column>

后来百度+文档得知 Swich 默认是 boolean 类型,而后台传值为 number 类型,此时用 number 来取代 boolean 类型 ,留意与前者的差别,同时@change 事件可以传值$event就是 switch 改变后的状态,scope.row 为行元素

API

<template slot-scope='scope'>
    <el-switch 
        v-model="scope.row.status"
        active-color="#13CE66"
        inactive-color="#C0CCDA"
        :active-value="1"
        :inactive-value="0"
        @change=changeComputerStatus($event,scope.row)>
    </el-switch>
</template>

文字描述

现在这个开关还没有和后台交互,只是可以拨动 😂 ,接下来需求就是根据后台的状态值 添加一个动态的字段 绿色显示启用灰色显示停用

官网的例子只有左右两边添加文字描述,不是我想要的结果,网上也是根据官网例子修改样式让描述显示在按钮上,也不是很好看,反反复复折腾了几个小时,崩溃了…

p2

p

后来询问群里大佬得到解决(感谢大佬)

仅仅一个简单的插值表达式就解决 {{ }} 😅 <switch></switch>{{ 变量名 }}

差值表达式不止能写变量,函数,表达式都能写

<template slot-scope='scope'>
    <el-switch 
        v-model="scope.row.status"
        active-color="#13CE66"
        inactive-color="#C0CCDA"
        :active-value="1"
        :inactive-value="0"
        @change=changeComputerStatus($event,scope.row)>
    </el-switch>
    {{ scope.row.status === 0 ? " 停用" : " 启用"}}
</template>

后台交互

接下来开始与后台交互,并操作 status 改变数据库字段值来实现启用关闭主机功能,直接上代码

element-ui

<el-table-column
    prop="status"
    label="状态" 
    align='center'
    width="150">
    <template slot-scope='scope'>
        <el-switch 
            v-model="scope.row.status"
            active-color="#13CE66"
            inactive-color="#C0CCDA"
            :active-value="1"
            :inactive-value="0"
            @change=changeComputerStatus($event,scope.row)>
        </el-switch>
        {{ scope.row.status === 0 ? " 停用" : " 启用"}}
     </template>
</el-table-column>

vue.js

// 改变主机状态: 1 开启 / 0 关闭
changeComputerStatus(changeStatus, row){
    const para = {id: row.id, status: changeStatus}
    updateComputerStatus(para).then(res => {
        this.$message({
            message: res.msg,
            type: 'success'
        })
        this.getComputerPage()
    }).catch(() => {
        row.status = !changeStatus * 1 //保持switch点击前的状态
    })
},

重点

catch(() => { }) 这块是执行失败的时候,我的场景是主机下面含有通道的且处于开启状态的则不能关闭该主机,后台返回 300 并返回错误信息,则该主机的状态开关应该如下图这样:

要实现如上图效果就是catch里的这句代码

catch(() => { row.status = !changeStatus * 1 }) //保持switch点击前的状态

解释一下:

changeStatus 就是即将改变的值,如果这条记录下面有通道且是开启状态,要关闭这台主机,后台就会返回 300,前台 axios 封装拦截,进入catch 语句 此时 changeStatus0 ,因为关闭状态为 0 ,现在前面加上 就是非 0 应该是 1(启用),但是加上 后它的返回值却成了 boolean 类型的,我们需要的是 1,而不是 true ,让它不能被停用,保持启用,解决办法是 * 1 就可以 true 转换成 1 😂 ,然后再赋值给 row.status 就实现了上图效果,这个可以应用于任何失败场景。

总结

终于算是写完了,记下来防止忘了,我的记忆只有3秒

god

溜了溜了,下班了

0B683415


随知修行乃当务之急,然怠惰度日至今。