用vue3做一个动态表格数据编辑

效果如下
用vue3配合elementPlus的表格组件和select实现
在这里插入图片描述
其中的功能点概括:
1:这里的表格中一行代表一个组 每个组都有删除功能,最后一个组有继续添加数据的功能
2:组别中有3个select选择器 分别对应不同的数据 其中的select有联动功能 选择到某个option 后面的select中的options列表需要动态改变值
3:保障每个组的数据之间互不干扰

话不多说 上代码-----

<script setup lang="ts">
const foodList = ref([
  {
    value: "米饭",
  },
  {
    value: "坚果",
  },
  {
    value: "酸奶",
  },
  {
    value: "牛肉",
  },
  {
    value: "苹果",
  },
  {
    value: "香蕉",
  },
  {
    value: "玉米",
  },
  {
    value: "烧烤",
  },
  {
    value: "鸡蛋",
  },
]);
const tableData = ref([
  {
    teamName: "",
    groupName: "",
    bspFlag: "",
    users: [],
    secondSelectOptions: [],
    showSecondSelect: false,
    showThirdSelect: false,
  },
]);
function handleFirstSelectChange(value: any) {
  value.groupName = "";
  value.secondSelectOptions = [];
  value.showSecondSelect = false;
  value.showThirdSelect = false;
  if (value.teamName === "早餐") {
    value.secondSelectOptions = [
      { value: "营养早餐", label: "营养早餐" },
      { value: "随便吃点", label: "随便吃点" },
      { value: "水果早餐", label: "水果早餐" },
      { value: "减脂早餐", label: "减脂早餐" },
    ];
    value.showSecondSelect = true;
    value.groupName = "营养早餐";
  } else if (value.teamName === "午餐") {
    // 保持第二个select为空且不显示
  } else if (value.teamName === "晚餐") {
    value.secondSelectOptions = [
      { value: "猪脚饭" },
      { value: "鸡腿饭" },
      { value: "炒粉炒面" },
      { value: "啤酒烧烤" },
    ];
    value.showSecondSelect = true;
    value.groupName = "猪脚饭";
  }

  // 如果选择了第二个select且值为'随便吃点',则显示第三个select
  if (value.groupName === "随便吃点") {
    value.showThirdSelect = true;
  }
}
function handleSecondChange(val: any) {
  val.showThirdSelect = false;
  if (val.groupName == "随便吃点") {
    val.showThirdSelect = true;
    val.bspFlag = "早点吃";
  }
}
function pushGroup() {
  tableData.value.push({
    teamName: "",
    groupName: "",
    bspFlag: "",
    users: [],
    secondSelectOptions: [],
    showSecondSelect: false,
    showThirdSelect: false,
  });
}
// 这里是使用索引来删除 考虑到当前项目不会出现很多数据 这样最快捷 如果涉及的数据过多 请自行生成id检索保证性能
function removeGroup(index: number) {
  tableData.value.splice(index, 1);
}
</script>

<template>
  <div>
    <el-table border :data="tableData" style="width: 100%">
      <el-table-column label="组别" align="center">
        <template #default="scope">
          <div style="display: flex; align-items: center; width: 100%">
            <div class="team_sel">
              <el-select
                v-model="scope.row.teamName"
                placeholder="请选择"
                style="width: 120px"
                @change="handleFirstSelectChange(scope.row)"
              >
                <el-option value="早餐" label="早餐"></el-option>
                <el-option value="午餐" label="午餐"></el-option>
                <el-option value="晚餐" label="晚餐"></el-option>
                <el-option value="其他" label="其他"></el-option>
              </el-select>
            </div>
            <div class="team_sel" v-show="scope.row.showSecondSelect">
              <el-select
                v-model="scope.row.groupName"
                placeholder="请选择"
                style="width: 120px"
                @change="handleSecondChange(scope.row)"
              >
                <el-option
                  v-for="(item, index) in scope.row.secondSelectOptions"
                  :key="index"
                  :value="item.value"
                  :label="item.label"
                ></el-option>
              </el-select>
            </div>
            <div class="team_sel" v-show="scope.row.showThirdSelect">
              <el-select
                v-model="scope.row.bspFlag"
                placeholder="请选择"
                style="width: 120px"
              >
                <el-option value="早点吃" label="早点吃"></el-option>
                <el-option value="晚点吃" label="晚点吃"></el-option>
              </el-select>
            </div>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="可选项" align="center">
        <template #default="scope">
          <div style="display: flex; align-items: center">
            <el-select multiple v-model="scope.row.users" placeholder="请选择">
              <el-option
                v-for="item in foodList"
                :label="item.value"
                :value="item.value"
              />
            </el-select>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" width="100">
        <template #default="scope">
          <div class="group_class" style="justify-content: space-around">
            <el-icon
              :size="20"
              @click="removeGroup(scope.$index)"
              color="#f56c6c"
              ><Remove
            /></el-icon>
            <el-icon
              :size="20"
              @click="pushGroup"
              color="#409eff"
              v-if="scope.$index == tableData.length - 1"
              ><CirclePlus
            /></el-icon>
          </div>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<style lang="scss" scoped>
.team_sel {
  width: 31%;
  margin-right: 10px;
  ::v-deep .el-select {
    width: 100% !important;
  }
  &:last-child {
    margin-right: 0;
  }
}
.group_class {
  display: flex;
  align-items: center;
  i {
    transition: color 0.3s;
  }
  i:hover { 	
    color: #409eff;
  }
}
</style>

这里主要需要注意的点是数据的绑定 原先没有直接绑定在tableData中 某一行更改的时候 就导致了所有的数据都收到了影响
所以这里后面取tableData的数据的时候 过滤一下按需取值就好了

这是最后获取的值
在这里插入图片描述

Vue 3 是一种流行的JavaScript框架,用于构建用户界面。要实现一个编辑表格,你可以按照以下步骤进行: 1. 创建一个Vue组件,用于表示整个表格。可以使用`<table>`元素来定义表格的结构。 2. 在组件的`data`选项中定义一个数组,用于存储表格数据。每个数组元素表示表格的一行数据。 3. 使用`v-for`指令在表格中循环渲染每一行数据,并显示每个单元格的值。 4. 为每个单元格添加一个点击事件,当用户点击单元格时,将其转换为可编辑状态。 5. 在可编辑状态下,将单元格替换为一个输入框或其他合适的编辑元素,并将其与数据绑定。 6. 监听输入框的变化,并更新数据数组中对应的值。 7. 提供保存或取消编辑功能,当用户完成编辑时,将编辑状态切换回普通状态,并保存或取消对数据的修改。 下面是一个简单的示例代码: ```html <template> <table> <tr v-for="(row, index) in tableData" :key="index"> <td v-for="(cell, cellIndex) in row" :key="cellIndex"> <span v-if="!cell.editable" @click="editCell(index, cellIndex)">{{ cell.value }}</span> <input v-else type="text" v-model="cell.value" @blur="saveCell(index, cellIndex)" @keydown.enter="saveCell(index, cellIndex)" @keydown.esc="cancelEdit(index, cellIndex)"> </td> </tr> </table> </template> <script> export default { data() { return { tableData: [ { value: 'Cell 1', editable: false }, { value: 'Cell 2', editable: false }, { value: 'Cell 3', editable: false } ] }; }, methods: { editCell(rowIndex, cellIndex) { this.tableData[rowIndex].editable = true; }, saveCell(rowIndex, cellIndex) { this.tableData[rowIndex].editable = false; }, cancelEdit(rowIndex, cellIndex) { this.tableData[rowIndex].editable = false; } } }; </script> ``` 这个示例中,我们使用了一个`tableData`数组来存储表格数据,每个元素包含一个`value`属性表示单元格的值,以及一个`editable`属性表示单元格是否可编辑。当用户点击单元格时,会调用`editCell`方法将单元格切换为可编辑状态,当用户完成编辑时,会调用`saveCell`方法保存修改,或调用`cancelEdit`方法取消编辑
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值