如何在 Vue 中创建一个带有表格和表单的弹窗

本文将通过一个具体的示例来介绍如何在 Vue 应用中实现一个带有表格和表单功能的弹窗组件。我们将使用 Element UI 库中的 el-dialog 组件来构建这个弹窗,并结合 el-table 和 el-form 来展示数据并允许用户进行编辑。

效果图:

完整代码最底部,以下拆分解析----------

1. 引入必要的 Element UI 组件
 

2. 创建弹窗结构
接下来定义弹窗的基本结构。这里我们使用 el-dialog 组件,并为其设置一些基本属性如标题、宽度等:

<el-dialog
  class="edit-dialog"
  title="编辑"
  width="80%"
  :center="true"
  ref="dialogRef"
  :visible.sync="dialogVisible"
  @close="resetForm('resetForm')"
  :before-close="beforeClose"
  :close-on-click-modal="false"
  :close-on-press-escape="false">
</el-dialog>

3. 添加表单和表格
在弹窗内部添加一个表单 (el-form) 和表格 (el-table),并通过 v-model 双向绑定数据

<el-form ref="formRef" style="padding: 20px" label-width="100px">
  <el-table
    border
    stripe
    class="table-style"
    max-height="350"
    :data="tableData"
    style="width: 100%; min-height: 200px;">
    <!-- 表格列定义 -->
  </el-table>
</el-form>

4. 定义表格列
为表格定义多个列,包括索引、发票类型选择器、输入框等:

<el-table-column type="index" label="序号" align="center" width="60" show-overflow-tooltip></el-table-column>
<el-table-column prop="invoiceType" label="发票类型" align="center" min-width="280">
  <template slot-scope="scope">
    <el-select
      multiple
      style="width: 100%"
      collapse-tags
      v-model="scope.row.invoiceTypeCode">
      <el-option
        v-for="(item, index) in typeList"
        :key="index"
        :label="item.invoiceTypeName"
        :value="item.invoiceTypeCode">
      </el-option>
    </el-select>
  </template>
</el-table-column>
<el-table-column prop="taxCategory" label="税收分类简称" align="center" min-width="180">
  <template slot-scope="scope">
    <el-input placeholder="请输入税收分类简称" v-model="scope.row.taxCategory" clearable></el-input>
  </template>
</el-table-column>
<el-table-column prop="taxRate" label="税率" align="center" min-width="180">
  <template slot-scope="scope">
    <el-input placeholder="请输入税率" v-model="scope.row.taxRate" clearable></el-input>
  </template>
</el-table-column>
<el-table-column prop="dateRange" label="适用时间" align="center" min-width="280">
  <template slot-scope="scope">
    <el-date-picker
      v-model="scope.row.dateRange"
      type="daterange"
      range-separator="至"
      value-format="yyyy-MM-dd"
      start-placeholder="开始日期"
      end-placeholder="结束日期">
    </el-date-picker>
  </template>
</el-table-column>
<el-table-column label="操作" align="center" width="80" :render-header="renderHeader">
  <template slot-scope="scope">
    <i @click.prevent="deleteRow(scope.$index, scope.row)" class="el-icon-delete"></i>
  </template>
</el-table-column>

5. 添加操作按钮
在弹窗底部添加两个按钮用于关闭和保存:

<div slot="footer">
  <el-button size="medium" @click="closeDialog">取消</el-button>
  <el-button size="medium" type="primary" ref="saveButton" @click="saveData('formRef')">保存</el-button>
</div>

6. 定义相关方法
最后,在 Vue 实例的方法部分定义与弹窗相关的处理逻辑,例如关闭时重置表单、保存数据等:

export default {
  data() {
    return {
      dialogVisible: false,
      tableData: [],
      typeList: [], // 示例数据
      formRef: null,
      dialogRef: null
    };
  },
  methods: {
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
    beforeClose(done) {
      this.resetForm('formRef');
      done();
    },
    deleteRow(index, row) {
      this.tableData.splice(index, 1);
    },
    closeDialog() {
      this.dialogVisible = false;
      this.resetForm('formRef');
    },
    saveData(formName) {
      this.$refs[formName].validate(valid => {
        if (valid) {
          // 保存数据逻辑
          console.log(this.tableData);
          this.closeDialog();
        }
      });
    },
    renderHeader(h, { column }) {
      return h('span', [
        h('i', { style: 'color: #409EFF' }, '添加行'),
        h('span', '操作')
      ]);
    }
  }
};

完整代码如下:

<template>
  <el-dialog
    title="编辑"
    width="80%"
    :center="true"
    ref="dialogRef"
    :visible.sync="dialogVisible"
    @close="resetForm('formRef')"
    :before-close="beforeClose"
    :close-on-click-modal="false"
    :close-on-press-escape="false">
    <el-form ref="formRef" style="padding: 20px" label-width="100px">
      <el-table
        border
        stripe
        class="custom-table"
        max-height="350"
        :data="tableData"
        style="width: 100%; min-height: 200px;">
        <el-table-column type="index" label="序号" align="center" width="60" show-overflow-tooltip></el-table-column>
        <el-table-column prop="invoiceType" label="发票类型" align="center" min-width="280">
          <template slot-scope="scope">
            <el-select
              multiple
              style="width: 100%"
              collapse-tags
              v-model="scope.row.invoiceTypeCode">
              <el-option
                v-for="item in typeList"
                :key="item.invoiceTypeCode"
                :label="item.invoiceTypeName"
                :value="item.invoiceTypeCode">
              </el-option>
            </el-select>
          </template>
        </el-table-column>
        <el-table-column prop="taxCategory" label="税收分类简称" align="center" min-width="180">
          <template slot-scope="scope">
            <el-input
              placeholder="请输入税收分类简称"
              v-model="scope.row.taxCategory"
              clearable>
            </el-input>
          </template>
        </el-table-column>
        <el-table-column prop="taxRate" label="税率" align="center" min-width="180">
          <template slot-scope="scope">
            <el-input
              placeholder="请输入税率"
              v-model="scope.row.taxRate"
              clearable>
            </el-input>
          </template>
        </el-table-column>
        <el-table-column prop="dateRange" label="适用时间" align="center" min-width="280">
          <template slot-scope="scope">
            <el-date-picker
              v-model="scope.row.dateRange"
              type="daterange"
              range-separator="至"
              value-format="yyyy-MM-dd"
              start-placeholder="开始日期"
              end-placeholder="结束日期">
            </el-date-picker>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="80" :render-header="renderHeader">
          <template slot-scope="scope">
            <i
              @click.prevent="deleteRow(scope.$index, scope.row)"
              class="el-icon-delete">
            </i>
          </template>
        </el-table-column>
      </el-table>
    </el-form>
    <div slot="footer">
      <el-button size="medium" @click="closeDialog">取消</el-button>
      <el-button size="medium" type="primary" ref="saveButton" @click="saveData('formRef')">保存</el-button>
    </div>
  </el-dialog>
</template>

<script>
export default {
  data() {
    return {
      dialogVisible: false,
      tableData: [
        {
          invoiceTypeCode: ['1'],
          taxCategory: '',
          taxRate: '',
          dateRange: []
        }
      ],
      typeList: [
        { invoiceTypeCode: '1', invoiceTypeName: '增值税专用发票' },
        { invoiceTypeCode: '2', invoiceTypeName: '增值税普通发票' }
      ]
    };
  },
  methods: {
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
    beforeClose(done) {
      this.resetForm('formRef');
      done();
    },
    deleteRow(index, row) {
      this.tableData.splice(index, 1);
    },
    closeDialog() {
      this.dialogVisible = false;
      this.resetForm('formRef');
    },
    saveData(formName) {
      this.$refs[formName].validate(valid => {
        if (valid) {
          console.log(this.tableData);
          this.closeDialog();
        }
      });
    },
    addNewRule() {
      this.tableData.push({
        invoiceTypeCode: [],
        taxCategory: '',
        taxRate: '',
        dateRange: [],
        isDisabled: false
      });
    },
    renderHeader(h, { column }) {
      return h(
        'div',
        [
          h('span', column.label),
          h('i', {
            class: 'el-icon-circle-plus',
            style: 'color: #409eff; font-size: 24px; cursor: pointer;',
            on: {
              click: this.addNewRule
            }
          })
        ]
      );
    }
  }
};
</script>

<style scoped>
.custom-dialog .el-dialog__body {
  padding: 20px;
}

.custom-table {
  margin-bottom: 20px;
}

.custom-table td, .custom-table .cell {
  padding: 0px;
}

.custom-table .el-input__inner {
  border-radius: 0;
}

.custom-table .el-icon-delete {
  cursor: pointer;
}

.custom-dialog .el-dialog__header {
  background: rgb(2, 65, 114);
  color: #fff;

  .el-dialog__title,
  .el-icon {
    color: #fff;
  }
}
</style>

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用 Element UI 的 Dialog 对话框组件来实现在表格点击按钮弹出弹窗的功能。具体实现步骤如下: 1. 在表格添加一个操作列,该列包含一个按钮,用于触发弹窗。 2. 在按钮绑定一个点击事件,该事件会调用一个方法。 3. 在该方法,使用 Element UI 的 Dialog 组件来创建一个弹窗,并设置弹窗的内容。 4. 在弹窗添加需要的表单元素或其他组件,并进行相关的操作。 下面是一个简单的代码示例,以帮助你更好地理解如何实现这个功能: ``` <template> <el-table :data="tableData"> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="age" label="年龄"></el-table-column> <<el-table-column label="操作"> <template slot-scope="scope"> <el-button type="primary" @click="handleClick(scope.row)">编辑</el-button> </template> </el-table-column> </el-table> <el-dialog :visible.sync="dialogVisible"> <el-form> <el-form-item label="姓名"> <el-input v-model="editRow.name"></el-input> </el-form-item> <el-form-item label="年龄"> <el-input v-model="editRow.age"></el-input> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="dialogVisible = false">取消</el-button> <el-button type="primary" @click="saveEdit">保存</el-button> </div> </el-dialog> </template> <script> export default { data() { return { tableData: [ { name: '张三', age: 18 }, { name: '李四', age: 20 } ], dialogVisible: false, editRow: {} } }, methods: { handleClick(row) { this.editRow = Object.assign({}, row) this.dialogVisible = true }, saveEdit() { // 在这里进行保存操作 this.dialogVisible = false } } } </script> ``` 在这个示例,我们在表格添加了一个“操作”列,该列包含一个“编辑”按钮。当用户点击该按钮时,会触发 `handleClick` 方法。该方法会将当前行的数据复制到 `editRow` 对象,并将 `dialogVisible` 属性设置为 `true`,以显示一个弹窗弹窗包含一个表单,用户可以在其编辑数据。当用户点击“保存”按钮时,会触发 `saveEdit` 方法,该方法可以在这里进行保存操作。最后,我们将 `dialogVisible` 属性设置为 `false`,以关闭弹窗。 需要注意的是,在这个示例,我们使用了 `Object.assign` 方法来创建一个新的对象,以确保我们不会直接修改原始数据。这是一个非常重要的步骤,因为直接修改原始数据可能会导致一些意外的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值