DeviceSwitch.vue 3.36 KB
<template>
<span>
  <!-- 开启confirm时,操作之前会先调动确认窗口 -->
  <el-popover
    v-if='confirm'
    placement="top"
    width="160"
    v-model="visible">
    <p>确认操作?</p>
    <div style="text-align: right; margin: 0">
      <el-button size="mini" type="text" @click="visible = false">取消</el-button>
      <el-button type="primary" size="mini" @click="statusClick">确定</el-button>
    </div>
    <label slot="reference" class="my-compontent-switch"
      :checked='checked'>
      <span>{{text}}</span>
    </label>
  </el-popover>

  <!-- 直接操作 -->
  <label 
    v-else
    class="my-compontent-switch"
    :checked='checked' 
    @click='statusClick'
  >
    <span>{{text}}</span>
  </label>
</span>
</template>

<script>
export default {
  props: {
    value: Array,
    row: Object,
    confirm: Boolean,
    on: {
      type: Object,
      default: ()=> {return {value: 1, text: '启用'}}
    },
    off: {
      type: Object,
      default: ()=> {return {value: 0, text: '停用'}}
    },
    url: String,
  },
  methods: {
    async statusClick() {
      console.log("value",this.value)
      const enabled = this.row.enabled === this.on.value ? this.off.value : this.on.value;
      const id = this.row.id;
      //const getTokenUrl = this.url.replace('/save', '/edit');
      // await this.$post(getTokenUrl, {id});
      this.$post(this.url, {
          enabled,
          id,
      })
      .then(res=>{
        // 更新数据
        let table = JSON.parse(JSON.stringify(this.value))
        console.log("table",table)
        let {index, data} = this.find(table, id);
        data.enabled = enabled;
        table.splice(index, 1, data);
        this.$emit("input", table);
        this.$emit("change");
      })
      .catch(error=>{
        this.$message.error(error.message);
      })
      .then(data=>{
        this.visible = false;
      })
    },
    find(list, id) {
      let index = -1;
      let data = null;
      list.forEach((item, i)=>{
        if(item.id === id){
          index = i;
          data = Object.assign({}, item);
          return;
        }
      })
      return {
        index,
        data,
      }
    },
  },
  computed: {
    text() {
      return this.row.enabled === this.on.value ? this.on.text : this.off.text;
    },
    checked() {
      return this.row.enabled === this.on.value;
    },
  },
  data() {
    return {
      visible: false,
    }
  }
}
</script>

<style lang="less">
.my-compontent-switch{
  display: inline-flex;
  align-items: center;
  position: relative;
  font-size: 12px;
  line-height: 19px;
  height: 20px;
  vertical-align: middle;
  &[checked] span{
    border-color: #409eff;
    background-color: #409eff;
    padding:0 23px 0 10px;
    &::after{
      left: 100%;
      margin-left: -17px;
    }
  }
  span{
    margin: 0;
    display: inline-block;
    position: relative;
    height: 20px;
    border: 1px solid #dcdfe6;
    outline: none;
    color: #fff;
    padding:0 10px 0 23px;
    border-radius: 10px;
    box-sizing: border-box;
    background: #dcdfe6;
    cursor: pointer;
    transition: border-color .3s,background-color .3s;
    vertical-align: middle;
    &::after{
      content: "";
      position: absolute;
      top: 1px;
      left: 1px;
      border-radius: 100%;
      transition: all .3s;
      width: 16px;
      height: 16px;
      background-color: #fff;
    }
  }
}
</style>