vue调用Element-ui 表格实现动态添加删除行数据及视图切换

vue调用Element-ui 表格实现动态添加删除行数据及视图切换

一、 预期效果如下

  1. 当不需要编辑时


    image.png

此时,表单部分网络结构名为下拉框,发布和图像类型为不可选择状态,其他输入框为只读状态;表格部分为正常的视图,不可编辑。

当对结构名进行选择后,表单和表格内容会进行初始化。

  1. 当需要进行编辑时


    image.png

这里以修改为例(新建雷同,区别为新建时表格和表单内容会清空)。

此时,表单部分:结构名由下拉框变为输入框,其他输入框由可读变为可编辑,类型也可以进行选择;表格部分新增添加和清空及操作栏按键,同时底部按键发生了部分变化,确定按键消失,复制、修改、新建、上传按键为不可点击状态(可视清空隐藏也可),同时新增了保存和取消按键,取消会将新建和修改后的数据清空,恢复最初的数据。

二、代码如下

部分需要调用后端接口的代码不进行展示了,按需添加

<template>
  <!--  卷积神经网络结构-->
  <div>
    <el-dialog v-bind="$attrs"
               v-on="$listeners"
               :close-on-click-modal="false"
               :close-on-press-escape="false"
               :visible.sync="show"
               width="50vw"
               align="center"
               :title="title">
      <!--  表单    -->
      <el-row :gutter="10">
        <el-form ref="elForm" :model="formData" :rules="rules" size="small" label-width="100px">
          <el-col :span="24">
            <el-form-item label-width="120px" label="网络结构名" prop="netStructureName">
              <!--  视图模式  -->
              <el-select v-model="formData.netId" placeholder="请选择网络结构名" clearable
                         :style="{width: '100%'}"
                         @change="initTableAndForm"
                         v-if="state === 'view'">
                <el-option v-for="(item, index) in netStructureNameOptions" :key="index" :label="item.netStructureName"
                           :value="item.netId" :disabled="item.disabled"></el-option>
              </el-select>
              <!--  编辑模式  -->
              <el-input v-model="formData.netStructureName" placeholder="请输入网络结构名" clearable
                        :style="{width: '100%'}"
                        v-if="state === 'edit' || state === 'add' || state === 'uploadV'"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label-width="120px" label="来源发布者" prop="netPublisher">
              <el-input v-model="formData.netPublisher" placeholder="请输入来源发布者" clearable
                        :style="{width: '100%'}"
                        :readonly="state === 'view'"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label-width="120px" label="发布类型" prop="netPublishedType">
              <el-select v-model="formData.netPublishedType" placeholder="请输入网络结构名" clearable
                         :style="{width: '100%'}"
                         :disabled="state === 'view'">
                <el-option v-for="(item, index) in netPublishedTypeOptions" :key="index" :label="item.label"
                           :value="item.value" :disabled="item.disabled"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label-width="120px" label="处理图像大小" prop="imgSize">
              <el-input v-model="formData.imgSize" placeholder="请输入处理图像大小" clearable
                        :style="{width: '100%'}"
                        :readonly="state === 'view'"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label-width="120px" label="图像类型" prop="imgStyle">
              <el-select v-model="formData.imgStyle" placeholder="请输入图像类型" clearable
                         :style="{width: '100%'}" :disabled="state === 'view'">
                <el-option v-for="(item, index) in imgStyleOptions" :key="index" :label="item.label"
                           :value="item.value" :readonly="item.disabled"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="备注" prop="memo">
              <el-input v-model="formData.memo" type="textarea" placeholder="请输入备注" :maxlength="100"
                        show-word-limit :autosize="{minRows: 3, maxRows: 4}"
                        :style="{width: '100%'}"
                        :readonly="state === 'view'"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="24" v-if="state === 'edit' || state === 'add' || state === 'uploadV'"
                  style="display: flex;justify-content: flex-end;">
            <el-button type="primary" size="small" @click="addRow" icon="el-icon-plus">
              添加
            </el-button>
            <el-button type="primary" size="small" @click="clearAll" icon="el-icon-delete">
              清空
            </el-button>
          </el-col>
        </el-form>
      </el-row>
      <br>
      <!--  表格    -->
      <el-table
          :data="tableData"
          size="mini"
          height="200px"
          border>
        <el-table-column
            type="index"
            align="center"
            label="序号"
            :index="indexMethod">
        </el-table-column>
        <el-table-column
            align="center"
            prop="layerStyle"
            label="层类型">
          <template v-slot="scope">
            <el-select v-model="scope.row.layerStyle" clearable placeholder="请输入层类型" size="mini"
                       v-if="state === 'edit' || state === 'add' || state === 'uploadV'">
              <el-option
                  v-for="item in layerStyleOptions"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value">
              </el-option>
            </el-select>
            <span v-if="state === 'view'">{{ scope.row.layerStyle }}</span>
          </template>
        </el-table-column>
        <el-table-column
            align="center"
            prop="kernelSize"
            label="卷积核大小">
          <template v-slot="scope">
            <el-input placeholder="请输入卷积核大小"
                      size="mini"
                      v-model="scope.row.kernelSize"
                      v-if="state === 'edit' || state === 'add' || state === 'uploadV'"></el-input>
            <span v-if="state === 'view'">{{ scope.row.kernelSize }}</span>
          </template>
        </el-table-column>
        <el-table-column
            align="center"
            prop="kernelCount"
            label="卷积核数量">
          <template v-slot="scope">
            <el-input placeholder="请输入卷积核数量"
                      size="mini"
                      v-model="scope.row.kernelCount"
                      v-if="state === 'edit' || state === 'add' || state === 'uploadV'"></el-input>
            <span v-if="state === 'view'">{{ scope.row.kernelCount }}</span>
          </template>
        </el-table-column>
        <el-table-column
            align="center"
            prop="stepSize"
            label="步长">
          <template v-slot="scope">
            <el-input placeholder="请输入步长"
                      size="mini"
                      v-model="scope.row.stepSize"
                      v-if="state === 'edit' || state === 'add' || state === 'uploadV'"></el-input>
            <span v-if="state === 'view'">{{ scope.row.stepSize }}</span>
          </template>
        </el-table-column>
        <el-table-column
            align="center"
            label="操作"
            width="120"
            v-if="state === 'edit' || state === 'add' || state === 'uploadV'">
          <template slot-scope="scope">
            <el-button type="text" size="small"
                       @click.native.prevent="addRow">新增
            </el-button>
            <el-button type="text" size="small"
                       @click.native.prevent="deleteRow(scope.$index, tableData)">删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <div slot="footer" align="center" style="margin-top: -3%">
        <el-button type="primary" size="small" @click="cloneShow"
                   :disabled="state === 'edit' || state === 'add' || state === 'copy' || state === 'uploadV'">复制
        </el-button>
        <el-button type="primary" size="small" @click="edit"
                   :disabled="state === 'edit' || state === 'add' || state === 'copy' || state === 'uploadV'">修改
        </el-button>
        <el-button type="primary" size="small" @click="add"
                   :disabled="state === 'edit' || state === 'add' || state === 'copy' || state === 'uploadV'">新建
        </el-button>
        <el-button type="primary" size="small"
                   v-show="state === 'view'"
                   @click="selectData">确定
        </el-button>
        <el-button type="primary" size="small"
                   v-show="state === 'edit' || state === 'add'"
                   @click="handleConfirm">保存
        </el-button>
        <el-button type="primary" size="small"
                   @click="uoloadSave"
                   v-show="state === 'uploadV'">保存
        </el-button>
        <el-button type="primary" size="small"
                   v-show="state === 'edit' || state === 'add' || state === 'copy' || state === 'uploadV'"
                   @click="handleCancel">取消
        </el-button>
      </div>
    </el-dialog>

    <el-dialog
        title="复制重命名"
        :close-on-click-modal="false"
        :close-on-press-escape="false"
        :visible.sync="dialogVisible">
      <el-form ref="form" :model="copyFormDataV1" label-width="120px" :rules="rulesV1">
        <el-form-item label="网络结构名" prop="newNetStructureName">
          <el-input v-model="copyFormDataV1.newNetStructureName"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="clone">确 定</el-button>
      </span>
    </el-dialog>

  </div>
</template>
<script>

export default {
  name: "networkStructure",
  // 避免父作用域的不被认作props的特性绑定应用在子组件的根元素上
  inheritAttrs: false,
  components: {},
  props: {},
  data() {
    return {
      fullscreenLoading: false,// 加载动画
      // 复制配置框
      dialogVisible: false,
      // 视图模式:查看view,新建add,编辑:edit,复制copy,上传:upload
      state: 'view',
      show: false,
      title:'默认',
      formData: {
        netId: undefined,
        netStructureName: undefined,
        netPublisher: undefined,
        netPublishedType: undefined,
        imgSize: undefined,
        imgStyle: undefined,
        cNNUpLoad: undefined,
        memo: undefined,
        aNodeCnnNetList: []
      },
      copyFormData: {
        aNodeCnnNetList: []
      },// 表单数据拷贝
      copyFormDataV1: {
        newNetStructureName: undefined
      },// 表单数据拷贝
      tableData: [/*{
        layerNo: 1,
        layerStyle: '卷积层',
        kernelSize: 3,
        kernelCount: 20,
        stepSize: 20,
      }*/],
      copyTableData: [],// 表格数据拷贝
      multipleSelection: [],
      rules: {
        netStructureName: [{
          required: true,
          message: '请输入网络结构名',
          trigger: 'blur'
        }],
        netPublisher: [{
          required: true,
          message: '请输入来源发布者',
          trigger: 'blur'
        }],
        netPublishedType: [{
          required: true,
          message: '发布类型不能为空',
          trigger: 'change'
        }],
        imgSize: [{
          required: true,
          message: '请输入处理图像大小',
          trigger: 'blur'
        }],
        imgStyle: [{
          required: true,
          message: '请输入图像类型',
          trigger: 'change'
        }],
        cNNUpLoad: [],
        memo: [],
      },
      // 复制弹窗重名名,非空验证
      rulesV1: {
        newNetStructureName: [{
          required: true,
          message: '请输入网络结构名',
          trigger: 'blur'
        }]
      },
      // 网络结构名,调用后端接口进行初始化
      netStructureNameOptions: [],
      // 卷积层类型
      layerStyleOptions: [{
        "label": "卷积层",
        "value": "卷积层"
      }, {
        "label": "池化层",
        "value": "池化层"
      }, {
        "label": "展平层",
        "value": "展平层"
      }, {
        "label": "全连接层",
        "value": "全连接层"
      }, {
        "label": "dropout",
        "value": "dropout"
      }],
      // 发布类型
      netPublishedTypeOptions: [{
        "label": "自定义",
        "value": "自定义"
      }, {
        "label": "外部共享",
        "value": "外部共享"
      }],
      // 图像类型
      imgStyleOptions: [{
        "label": "黑白",
        "value": 1
      }, {
        "label": "彩色",
        "value": 3
      }],
    }
  },
  computed: {},
  watch: {
    // 监听弹窗状态,当弹窗关闭可以进行部分数据的初始化
    show(val) {
      if (!val) {
        this.copyFormData = {
          aNodeCnnNetList: []
        };
        this.copyTableData = [];
        this.reset()
        //视图切换
        this.state = "view";
      }
    }
  },
  created() {
    this.getNetStructureList()
  },
  mounted() {
  },
  methods: {
    //获取全部网络结构名称,初始化下拉框
    getNetStructureList() {
      //调用后端接口
    },
    //下拉框选择,初始化表单和表格数据
    initTableAndForm(data) {
      // eslint-disable-next-line no-console
      console.log(data);
    },
    // 卷积网络架构修改
    edit() {
      if (this.formData.netStructureName != undefined) {
        // 数据克隆,方便取消还原数据
        this.copyFormData = JSON.parse(JSON.stringify(this.formData))
        this.copyTableData = JSON.parse(JSON.stringify(this.tableData))
        //视图切换
        this.state = 'edit'
      } else {
        this.$message.warning({
          title: '警告',
          message: "请先对网络结构名进行选择~",
          duration: 2000
        })
      }
    },
    // 克隆重命名弹窗展示
    cloneShow() {
      if (this.formData.netStructureName != undefined) {
        this.dialogVisible = true
      } else {
        this.$message.warning({
          title: '警告',
          message: "请先对网络结构名进行选择~",
          duration: 2000
        })
      }
    },
    // 复制卷积网络结构
    clone() {
      // 数据克隆及复制,表格对象封装到表格对象中
      if (this.formData != undefined) {
        this.copyFormData = JSON.parse(JSON.stringify(this.formData))
        this.copyFormData.netStructureName = this.copyFormDataV1.newNetStructureName
      }
      if (this.tableData != undefined) {
        this.copyTableData = JSON.parse(JSON.stringify(this.tableData))
        this.copyFormData.aNodeCnnNetList = this.copyTableData
      }
      //视图切换
      this.state = 'copy'
      // eslint-disable-next-line no-console
    },
    // 确定选择该架构
    selectData() {
      if (this.formData.netStructureName != undefined) {
        this.$emit("networkStructure", this.formData)
        this.show = false
      } else {
        this.$message.warning({
          title: '警告',
          message: "请先对网络结构名进行选择~",
          duration: 2000
        })
      }
    },
    // 新建卷积网络结构
    //新建的时候先拷贝,再进行表单,表格重置
    add() {
      if (this.formData != undefined) {
        this.copyFormData = JSON.parse(JSON.stringify(this.formData))
      }
      if (this.tableData != undefined) {
        this.copyTableData = JSON.parse(JSON.stringify(this.tableData))
      }
      // this.$refs['elForm'].resetFields() 初始化表单,非清空
      this.reset()
      // 视图切换
      this.state = 'add'
    },
    // 保存修改,新建的内容
    handleConfirm() {
      this.$refs['elForm'].validate(valid => {
        if (valid) {
          // eslint-disable-next-line no-console
          console.log(valid)
        }
      })
    },
    // 取消新建,修改状态,并还原数据
    handleCancel() {
      this.tableData = JSON.parse(JSON.stringify(this.copyTableData))
      this.formData = JSON.parse(JSON.stringify(this.copyFormData))
      //视图切换
      this.state = 'view'
    },
    // 表格删除行数据
    deleteRow(index, rows) {
      rows.splice(index, 1);
    },
    // 表格新增行数据
    addRow() {
      if (this.tableData == undefined) {
        this.tableData = new Array();
      }
      let obj = {};
      this.tableData.push(obj);
    },
    // 表格清空所有行
    clearAll() {
      this.tableData = undefined
    },
    // 表格自定义序列号
    indexMethod(index) {
      return index + 1;
    },
    //表单,表格重置
    reset() {
      this.formData = {
        netStructureName: undefined,
        netPublisher: undefined,
        netPublishedType: undefined,
        imgSize: undefined,
        imgStyle: undefined,
        cNNUpLoad: undefined,
        memo: undefined,
        aNodeCnnNetList: []
      },
          this.tableData = undefined
    }
  }
}
</script>

<style>
</style>

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容