vue 三状态开关

1、没入门前端,猎奇心理仅此而已

2、因为想用python + vue 仿写一个 testlink,所以就 试试水,,,

3、python 后端已经干完了 用的django+drf

言归正传

先看效果 大概是这样,细节还需要调整一下

 

这种三状态开关,是想看用例的状态,不需要下拉框直接在列表里面直接执行触发接口

 threeStatusSwitch.vue

<template>
    <div>
      <ul
        class="toggle-switch"
        :class="{'square' : defaultOptions.layout.squareCorners}"
        :style="toggleSwitchStyle"
      >
          <li
          :style="itemStyle"
          v-for="(label, index) in defaultOptions.items.labels"
          :key="index">
              <input
              :disabled="defaultOptions.items.disabled || disabled"
              :id="label.name + group" :value="label.name"
              :name="name"
              type="radio"
              @click="toggle">
              <label
                  v-if="label.name === selectedItem"
                  :style="labelStyleSelected(label.color, label.backgroundColor)"
                  :class="{ active: !defaultOptions.items.disabled || disabled}"
                  class="selected"
                  :for="label.name + group"
                  type="radio"
                  >{{label.name}}
              </label>
              <label
              v-else
              :style="labelStyle"
              :class="{active: !defaultOptions.items.disabled || disabled}"
              :for="label.name + group"
              type="radio">
              </label>
          </li>
      </ul>
    </div>
  </template>
  
  <script>
  const s = x => x + 's'
  const rem = v => v + 'rem'
  export default {
    name: 'threeStatusSwitch',
    props: {
      options: {
        type: Object,
        required: false
      },
      value: {
        type: String,
        required: false
      },
      name: {
        type: String,
        required: false
      },
      group: {
        type: String,
        required: false,
        default: ''
      },
      disabled: {
        type: Boolean,
        required: false,
        default: false
      }
    },
    created () {
      this.defaultOptions = {
        layout: {
          color: 'black',
          backgroundColor: 'white',
          selectedColor: 'white',
          selectedBackgroundColor: 'green',
          borderColor: 'gray',
          fontFamily: 'Arial',
          fontWeight: 'normal',
          fontWeightSelected: 'normal',
          squareCorners: false,
          noBorder: false
        },
        size: {
          fontSize: 0.5,
          height: 3.25,
          padding: 0.5,
          width: 10
        },
        items: {
          delay: 0.4,
          preSelected: this.value,
          disabled: false,
          labels: [
            { name: '失败', color: 'white', backgroundColor: 'red' },
            { name: '未执行', color: 'white', backgroundColor: 'grey' },
            { name: '通过', color: 'white', backgroundColor: 'green' }
          ]
        }
      }
    },
    mounted () {
      if (this.options !== null && this.options !== undefined) {
        this.mergeDefaultOptionsWithProp(this.options)
      }
      if (this.defaultOptions.items.preSelected !== 'unknown') {
        this.selectedItem = this.defaultOptions.items.preSelected
        this.$emit('input', this.selectedItem)
      } else if (this.value) {
        this.selectedItem = this.value
        this.$emit('input', this.selectedItem)
      }
    },
    data () {
      return {
        selected: false,
        selectedItem: '未执行',
        defaultOptions: Object
      }
    },
    computed: {
      toggleSwitchStyle () {
        return {
          width: rem(this.defaultOptions.size.width),
          height: rem(this.defaultOptions.size.height)
        }
      },
      itemStyle () {
        return {
          width: rem(this.defaultOptions.size.width),
          height: rem(this.defaultOptions.size.height),
          fontFamily: this.defaultOptions.layout.fontFamily,
          fontSize: rem(this.defaultOptions.size.fontSize),
          textAlign: 'center'
        }
      },
      labelStyle () {
        return {
          padding: rem(this.defaultOptions.size.padding),
          borderColor: this.defaultOptions.layout.noBorder ? 'transparent' : this.defaultOptions.layout.borderColor,
          backgroundColor: this.defaultOptions.layout.backgroundColor,
          color: this.defaultOptions.layout.color,
          fontWeight: this.defaultOptions.layout.fontWeight,
          transition: s(this.defaultOptions.items.delay)
        }
      }
    },
    methods: {
      toggle (event) {
        if (!this.defaultOptions.items.disabled) {
          this.selected = true
          this.selectedItem = event.target.id.replace(this.group, '')
          this.$emit('selected',this.selectedItem)
          this.$emit('input', this.selectedItem)
          this.$emit('change', {
            value: event.target.id.replace(this.group, ''),
            srcEvent: event
          })
        }
      },
      labelStyleSelected (color, backgroundColor) {
        return {
          padding: rem(this.defaultOptions.size.padding),
          borderColor: this.defaultOptions.layout.noBorder ? 'transparent' : this.defaultOptions.layout.borderColor,
          fontWeight: this.defaultOptions.layout.fontWeightSelected,
          backgroundColor: backgroundColor !== undefined ? backgroundColor : this.defaultOptions.layout.selectedBackgroundColor,
          color: color !== undefined ? color : this.defaultOptions.layout.selectedColor,
          transition: s(this.defaultOptions.items.delay)
        }
      },
      mergeDefaultOptionsWithProp (options) {
        var result = this.defaultOptions
        for (var option in options) {
          if (options[option] !== null && typeof (options[option]) === 'object') {
            for (var subOption in options[option]) {
              if (options[option][subOption] !== undefined && options[option][subOption] !== null) {
                result[option][subOption] = options[option][subOption]
              }
            }
          } else {
            result[option] = options[option]
          }
        }
      }
    },
    watch: {
      value (val) {
        this.selectedItem = val
      },
      options (val) {
        if (val !== null && val !== undefined) {
          this.mergeDefaultOptionsWithProp(val)
        }
      }
    }
  }
  </script>
  
  <style lang="scss" scoped>
  ul {
    list-style: none;
  }
  label {
    margin: 0;
  }
  .toggle-switch {
    padding: 0;
    margin: 0;
    display: inline-flex;
  }
  .square li:first-child label {
    border-top-left-radius: 0 !important;
    border-bottom-left-radius: 0 !important;
  }
  .square li:last-child label {
    border-top-right-radius: 0 !important;
    border-bottom-right-radius: 0 !important;
  }
  .toggle-switch li {
    position:relative;
  }
  .toggle-switch li label{
    border-right-color: white !important;
  }
  .toggle-switch li:first-child label {
    border: 1px solid;
    border-top-left-radius: 5px;
    border-bottom-left-radius: 5px;
  }
  .toggle-switch li:last-child label {
    border-right: 1px solid;
    border-top: 1px solid;
    border-bottom: 1px solid;
    border-top-right-radius: 5px;
    border-bottom-right-radius: 5px;
    border-right-color: gray !important;
  }
  .toggle-switch label, .toggle-switch input {
    display:block;
    position:absolute;
    top:0;
    left:0;
    right:0;
    bottom:0;
  }
  .toggle-switch input[type="radio"] {
    opacity:0.01;
    z-index:100;
  }
  .toggle-switch li:not(:first-child):not(:last-child) label {
    border-right: 1px solid;
    border-top: 1px solid;
    border-bottom: 1px solid;
  }
  .active {
    cursor: pointer;
  }
  </style>

execSwitch.vue

<template>
    <div>
        <div>
            <el-table :data="dataList" :row-class-name="table_row_class_name" :border="true" style="font-size:1px">
                <el-table-column label="序号" type="id" width="50"></el-table-column>
                <el-table-column prop="name" label="名称"></el-table-column>
                <el-table-column prop="steps" label="步骤">
                    <template #default="scope">
                        <div v-html="scope.row.steps"></div>   
                    </template>
                </el-table-column>
                <el-table-column prop="status" label="状态">
                    <template   #default="scope">
                        <threeStatusSwitch  v-if="scope.row.status === 0" value="未执行" @selected="(case_status_name)=>change_case_status(case_status_name, scope.row)"/>
                        <threeStatusSwitch v-if="scope.row.status === 1" value="通过" @selected="(case_status_name)=>change_case_status(case_status_name, scope.row)"/>
                        <threeStatusSwitch v-if="scope.row.status === 2" value="失败" @selected="(case_status_name)=>change_case_status(case_status_name, scope.row)"/>
                    </template>
                </el-table-column>
            </el-table>

        </div>
    </div>

</template>
<script>
import threeStatusSwitch from './components/threeStatusSwitch.vue';
import {ref} from 'vue'
export default {
    name: "exec_switch",
    components: { threeStatusSwitch },
    setup() {
        const tableLoading = false;
        let value = ref('');
        let dataList = [
            {
                id: 1,
                name: 'test_1',
                steps: '1、某某<br/>2、某XX<br/>3、CC<br/>4、SS<br/>5、DDFF',
                status: 0
            },
            {
                id: 2,
                name: 'test_2',
                steps: '1、某某<br/>2、某XX<br/>3、CC<br/>4、SS<br/>5、DDFF',
                status: 1
            },
            {
                id: 3,
                name: 'test_3',
                steps: '1、某某<br/>2、某XX<br/>3、CC<br/>4、SS<br/>5、DDFF',
                status: 2
            },    
        ];
        const change_case_status = (case_status_name, case_info)=> {
            console.log(case_info.id, 'case_id');
            console.log(case_info.status, 'case_status');
            console.log(case_status_name,'ecase_status_name')
            var case_status = case_info.status;
            if (case_status_name === '通过'){case_status=1}
            else if (case_status_name === '失败'){case_status=2}
            else{case_status=0}
            case_info.status = case_status
            console.log(case_status, '执行后的case状态');
        };
        const table_row_class_name = ({row}) => {
            if (row.status === 2) {
                return 'warning-row'
            } else if (row.status === 1) {
                return 'success-row'
            }
            else {return ''}
        };
        
        return { dataList, tableLoading, value, change_case_status, table_row_class_name }
    },
    
};

</script>

<style>
    .el-table .warning-row {
        
      --el-table-tr-bg-color: rgb(228, 109, 109);
    }
    .el-table .success-row {
      --el-table-tr-bg-color: rgb(102, 241, 102);
    }
</style>

参考链接:GitHub - naveenraina/vuejs-three-state-switch

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值