ele-table表格列表内,双击编辑部分信息(el-table组件同理)

说明

ele-table 为公司内部组件,重点看 【主要代码】 部分代码
ele-table表格列表内:双击需要编辑的区域,编辑部分信息

实现

双击需要编辑的数据,展示输入框/日期选择,

  • 展示输入框:修改完之后,按键盘回车键,提交修改数据
  • 展示日期选择:修改完之后,点击 √ 按钮,提交修改数据

页面展示


代码

html 复制代码
<!-- 机动车巡查 -->
<template>
  <div class="container">
    <ele-form-search
      class="container_search"
      :form-data="searchData"
      :form-desc="searchDesc"
      @search="fetchData"
    />

    <div class="container_btn">
      <el-button class="el-icon-plus" type="primary" size="mini" @click="operationHandler('add')">
        录入
      </el-button>
      <el-button size="mini" @click="operationHandler('auto')">自动录入设置</el-button>
      <a href="/downloadCenter/核查处理通知书.docx">
        <el-button size="mini">整改说明书下载</el-button>
      </a>
    </div>
    <ele-table
      class="contariner_table"
      :table-options="options"
      :columns-options="columns"
      :page.sync="searchData.page"
      :page-size.sync="searchData.rows"
      :total="total"
      :show-fixed-control="false"
    >
      <template #sffxwt="{ row }">
        <el-switch
          v-model="row.sffxwt"
          active-color="#13ce66"
          active-value="yes"
          inactive-value="no"
          @change="sffxwtChange($event, row)"
        >
        </el-switch>
      </template>
      <!-- 【主要代码】 start -->
      <template #czwt="{ row }">
        <el-input
          v-if="row.czwtIsEdit"
          v-model="editValue"
          placeholder="请输入内容"
          size="mini"
          @keyup.enter.native="dbClickSubmit('czwt', row)"
        ></el-input>
        <span v-else @dblclick="dbClickEdit('czwt', row)">{{ row.czwt }}</span>
      </template>
      <template #ccrq="{ row }">
        <div v-if="row.ccrqIsEdit" class="ccrq">
          <el-date-picker
            v-model="editValue"
            type="date"
            placeholder="选择日期"
            size="mini"
            format="yyyy-MM-dd"
            value-format="yyyy-MM-dd"
          />
          <el-button
            type="text"
            class="el-icon-check"
            @click="dbClickSubmit('ccrq', row)"
          ></el-button>
        </div>

        <span v-else @dblclick="dbClickEdit('ccrq', row)">{{ row.ccrq }}</span>
      </template>
      <!-- 【主要代码】 end -->

      <template #operation="{ row }">
        <el-button type="text" @click="detailHandler(row)">查看</el-button>
        <el-button
          :disabled="row.sffxwt === 'no'"
          type="text"
          @click="operationHandler('upload', row)"
          >上传</el-button
        >
        <el-button type="text" @click="operationHandler('issued', row)">下发</el-button>
      </template>
    </ele-table>

    <DetailDialog ref="DetailDialogRef" @update="fetchData" />
    <OperationDialog ref="OperationDialogRef" @update="fetchData" />
  </div>
</template>
<script>
import { mapGetters } from 'vuex'
import { listPage, update } from '@/api/neimeng/vehicle-inspection-feedback'
import { searchDesc } from './constant/formList'
import { columns } from './constant/columns'
import DetailDialog from './components/DetailDialog'
import OperationDialog from './components/OperationDialog'

export default {
  name: 'VehicleInspection',
  components: { DetailDialog, OperationDialog },

  filters: {},
  data() {
    return {
      searchData: {
        page: 1,
        rows: 10
      },
      tableData: [],
      total: 0,
      editValue: ''
    }
  },

  computed: {
    ...mapGetters(['glbmList']),
    searchDesc() {
      return searchDesc(this)
    },
    options() {
      return {
        data: this.tableData
      }
    },
    columns() {
      return columns(this)
    }
  },

  watch: {},

  created() {
    this.fetchData()
  },

  methods: {
    fetchData() {
      let { time, ...params } = this.searchData
      if (time && time.length) {
        params.kssj = time[0]
        params.jssj = time[1]
      }
      listPage(params).then((res) => {
        this.common.CheckCode(res, null, () => {
          this.tableData = res.data.rows || []
          this.total = res.data.total || 0
        })
      })
    },
    sffxwtChange(val, row) {
      update({
        sffxwt: val,
        id: row.id
      }).then((res) => {
        this.$common.CheckCode(res, null, () => {
          this.fetchData()
        })
      })
    },
    /** ** 【主要代码】 start ****/
    getIndex(rowData) {
      return this.tableData.findIndex((item) => item.id === rowData.id)
    },
    dbClickEdit(key, rowData) {
      const isCanEdit = this.tableData.some((item) => {
        if (item.ccrqIsEdit || item.czwtIsEdit) return true
      })
      if (isCanEdit) return this.$message.error('请先编辑完当前数据再编辑下一个')
      this.editValue = key === 'ccrq' ? new Date(rowData[key]) : rowData[key]

      this.tableData[this.getIndex(rowData)][key + 'IsEdit'] = true
      this.renderDom()
    },
    dbClickSubmit(key, rowData) {
      update({
        [key]: this.editValue,
        id: rowData.id
      }).then((res) => {
        this.$common.CheckCode(res, '修改成功', () => {
          this.fetchData()
          this.tableData[this.getIndex(rowData)][key + 'IsEdit'] = false
          this.renderDom()
          this.editValue = ''
        })
      })
    },
    renderDom() {
      this.tableData.push({})
      this.tableData.pop()
    },
    /** ** 【主要代码】 end ****/
    detailHandler(rowData) {
      this.$refs.DetailDialogRef.open(rowData)
    },
    operationHandler(type, rowData) {
      this.$refs.OperationDialogRef.open(type, rowData)
    }
  }
}
</script>
<style lang="scss" scoped>
.container {
  height: calc(100% - 52px);

  &_search {
    padding: 10px;
    margin-bottom: 10px;
    ::v-deep .el-form-item__content {
      text-align: left;
    }
  }

  &_btn {
    background-color: #fff;
    padding: 10px 10px 0;
    text-align: left;
    .el-icon-plus {
      margin-bottom: 10px;
    }
    a {
      margin-left: 10px;
    }
  }
  .contariner_table {
    height: calc(100% - 100px);

    ::v-deep .ele-table-pagination {
      position: fixed;
      bottom: 0;
      justify-content: center;
      z-index: 10;
    }
    .upload-demo {
      display: inline-block;
    }
    .ccrq {
      width: 100%;
      display: inline-block;
      ::v-deep .el-date-editor {
        width: calc(100% - 22px);
      }
      .el-icon-check {
        padding: 0;
        cursor: pointer;
        font-size: 20px;
      }
    }
  }
}

.blue-theme {
  .container_btn {
    background-color: #293f60;
    color: #fff;
  }
}
.night-theme {
  .container_btn {
    background-color: #1a2331;
    color: #fff;
  }
}
</style>

./constant/formList.js

js 复制代码
import { getToken } from '@/utils/auth'

const sffxwtOptions = [
  {
    value: 'yes',
    text: '是'
  },
  {
    value: 'no',
    text: '否'
  }
]

export const searchDesc = (_this) => {
  return {
    jczmc: {
      type: 'input',
      label: '监测站名称',
      attrs: {
        clearable: true
      },
      layout: 8
    },
    fzjg: {
      type: 'input',
      label: '盟市',
      attrs: {
        clearable: true
      },
      layout: 8
    },
    sffxwt: {
      type: 'select',
      label: '是否发现问题',
      attrs: {
        clearable: true
      },
      layout: 8,
      options: sffxwtOptions
    },
    time: {
      type: 'daterange',
      label: '巡查时间',
      attrs: {
        clearable: true,
        valueFormat: 'yyyy-MM-dd'
      },
      layout: 8
    }
  }
}

export const detailFormDesc = (_this) => {
  return {
    carInfo: {
      hpzl: {
        type: 'select',
        label: '号牌种类',
        layout: 8,
        render: (h, content, value) => {
          return <span>{_this.common.filter_dic('mon_business_hpzl', value)}</span>
        }
      },
      hphm: {
        type: 'input',
        label: '号牌号码',
        layout: 8
      },
      jdczt: {
        type: 'input',
        label: '机动车状态',
        layout: 8
      },
      syr: {
        type: 'input',
        label: '所有人',
        layout: 8
      },
      sfzmhm: {
        type: 'input',
        label: '身份证号',
        layout: 8
      },
      lxfs: {
        type: 'input',
        label: '联系方式',
        layout: 8
      },
      zsxxdz: {
        type: 'input',
        label: '住址',
        layout: 8
      },
      zzxxdz: {
        type: 'input',
        label: '暂住地址',
        layout: 8
      },
      ccdjrq: {
        type: 'input',
        label: '初次登记日期',
        layout: 8
      },
      yxqz: {
        type: 'input',
        label: '有效期止',
        layout: 8
      },
      qzbfqz: {
        type: 'input',
        label: '强制报废日期止',
        layout: 8
      },
      yqjyqzbfqz: {
        type: 'input',
        label: '逾期检验强制报废期止',
        layout: 8
      },
      syq: {
        vif: _this.drawerType === 'detail',
        type: 'input',
        label: '所有权',
        layout: 8,
        render: (h, content, value) => {
          const cur = sffxwtOptions.find((i) => i.value === value)
          return <span>{(cur && cur.text) || '暂无'}</span>
        }
      },
      sqztmc: {
        vif: _this.drawerType === 'detail',
        type: 'input',
        label: '申请状态',
        layout: 8
      },
      bz: {
        vif: _this.drawerType === 'detail',
        type: 'input',
        label: '车辆备注信息',
        layout: 8
      }
    },
    applyInfo: {
      clbz: {
        type: 'input',
        label: '车辆备注信息',
        layout: _this.drawerType === 'apply' ? 24 : 8,
        default: _this.carInfo.bz,
        disabled: true
      },
      [_this.drawerType === 'apply' ? 'zrbm' : 'zrbmmc']: {
        type: 'select',
        label: '申请转入部门',
        layout: _this.drawerType === 'apply' ? 24 : 8,
        required: true,
        options: _this.glbmOptions,
        prop: {
          value: 'value',
          text: 'label'
        },
        attrs: {
          clearable: true
        }
      },
      bz: {
        type: 'textarea',
        label: '申请备注',
        layout: _this.drawerType === 'apply' ? 24 : 8,
        attrs: {
          clearable: true
        }
      },
      cjr: {
        vif: ['examineDetail', 'examine'].includes(_this.drawerType),
        type: 'input',
        label: '申请人',
        layout: 8
      },
      sqbm: {
        vif: ['examineDetail', 'examine'].includes(_this.drawerType),
        type: 'input',
        label: '申请人部门',
        layout: 8
      },
      sqsj: {
        vif: ['examineDetail', 'examine'].includes(_this.drawerType),
        type: 'input',
        label: '申请时间',
        layout: 8
      }
    },
    examineInfo: {
      clyj: {
        type: 'textarea',
        label: '审核备注',
        layout: _this.drawerType === 'examine' ? 24 : 16,
        attrs: {
          clearable: true
        }
      },
      clr: {
        vif: ['examineDetail'].includes(_this.drawerType),
        type: 'input',
        label: '审核人',
        layout: 8
      },
      clsj: {
        vif: ['examineDetail'].includes(_this.drawerType),
        type: 'input',
        label: '审核时间',
        layout: 16
      }
    }
  }
}

export const operationFormDesc = (_this) => {
  return {
    auto: {
      lrpl: {
        type: 'input',
        label: '',
        labelWidth: 0,
        layout: 24
      },
      lrsl: {
        type: 'input',
        label: '',
        labelWidth: 0,
        layout: 24
      }
    },
    issued: {
      xfbm: {
        type: 'select',
        label: '下发部门',
        layout: 24,
        options: _this.glbmOptions,
        prop: {
          value: 'value',
          text: 'label'
        },
        attrs: {
          clearable: true
        }
      }
    },
    upload: {
      zgsms: {
        type: 'upload',
        label: '上传文件',
        layout: 24,
        attrs: {
          // accept: 'image/*',
          label: '上传文件',
          multiple: false,
          autoUpload: true,
          limit: 1,
          // listType: 'picture-card',
          blockSize: 'middle',
          params: { relativePath: 'NMXCFile/' },
          uploadAPI: '/supervise_basic/upload/oss/fileupload',
          token: getToken(),
          beforeUpload: _this.beforeUploadHandler,
          'on-exceed': () => {
            _this.$message('最多允许传一个文件')
          }
        }
      }
    }
  }
}

./constant/columns.js

js 复制代码
import moment from 'moment'
export const columns = (_this) => {
  return [
    {
      type: 'index',
      label: '序号',
      index: (index) => {
        return (_this.searchData.page - 1) * _this.searchData.rows + index + 1
      }
    },
    {
      prop: 'fzjg',
      label: '盟市'
    },
    {
      prop: 'lsh',
      label: '流水号'
    },
    {
      prop: 'jczmc',
      label: '监测站名称'
    },
    {
      prop: 'hphm',
      label: '车牌号'
    },
    {
      prop: 'cllx',
      label: '车辆类型'
    },
    {
      prop: 'sffxwt',
      label: '是否发现问题'
    },
    {
      prop: 'czwt',
      label: '存在问题'
    },
    {
      prop: 'ccrq',
      label: '抽查日期'
    },
    {
      prop: 'operation',
      label: '操作',
      fixed: 'right',
      width: 150
    }
  ]
}
相关推荐
夫琅禾费米线35 分钟前
[有趣的JavaScript] 为什么typeof null返回 object
开发语言·前端·javascript
三掌柜66635 分钟前
【腾讯云产品最佳实践】腾讯云CVM入门技术与实践:通过腾讯云快速构建云上应用
开发语言·腾讯云·perl
多来米199636 分钟前
小白学多线程(持续更新中)
java·开发语言
小柯J桑_4 小时前
C++:探索AVL树旋转的奥秘
开发语言·c++·avl树
nothing_more_than5 小时前
draggable的el-dialog实现对话框标题可以选择
javascript·vue.js·element-plus
skaiuijing5 小时前
Sparrow系列拓展篇:消息队列和互斥锁等IPC机制的设计
c语言·开发语言·算法·操作系统·arm
小镇程序员6 小时前
vue2 src自定义事件
前端·javascript·vue.js
炒毛豆6 小时前
vue3+echarts+ant design vue实现进度环形图
javascript·vue.js·echarts
雯0609~6 小时前
c#:winform调用bartender实现打印(学习整理笔记)
开发语言·c#