整体

<template>
    <div class="project_main">
      <div class="alert_box">
        <el-alert v-if="alert.show" :title="alert.title" :type="alert.type" closable @close="handleAlertClose" />
      </div>
      <el-dialog v-model="confirmdialog" title="Warning" width="30%" center>
      <span>Confirm deleting this data row
      </span>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="confirmdialog = false">Cancel</el-button>
          <el-button type="primary" @click="confirmDelete">
            Confirm
          </el-button>
        </span>
      </template>
    </el-dialog>
      <div class="search_box">
        <el-form :inline="true" class="search_info">
            <el-form-item label="project:">
              <el-input v-model="projectname" placeholder="项目名" clearable />
            </el-form-item>
            <el-form-item label="owner:" >
              <el-input v-model="projectowner" placeholder="负责人" clearable />
            </el-form-item>
            <el-form-item label="rank:">
            <el-select
              v-model="projectrank"
              class="m-2"
              placeholder="Select"
              size="large"
              style="width: 240px"
              clearable 
            >
              <el-option
                v-for="item in options"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        <el-form-item>
            <el-button type="primary" @click="handleSubmit(1,10,projectname,projectowner,projectrank)">Query</el-button>
          </el-form-item>
          <el-form-item>
          <el-button type="primary" class="add_row" @click="handleAdd">Add</el-button>
        </el-form-item>
        </el-form>
      </div>
      <div class="project_table_box">
        <el-table :data="projectlist" style="width: 100%" :row-height="rowHeight">
          <el-table-column fixed prop="project_name" label="项目名" width="150">
            <template #default="{ row }">
              <span v-if="!row.editing && !row.addediting">{{ row.project_name }}</span>
              <el-input
                v-else
                v-model="row.editName"
              ></el-input>
            </template>
          </el-table-column>
          <el-table-column prop="project_rank" label="重要等级" width="140" >
            <template #default="{ row }">
              <span v-if="!row.editing && !row.addediting">{{ row.project_rank }}</span>
              <el-select
              v-else
              v-model="row.editRank"
              class="m-2"
              placeholder="Select"
              size="large"
              style="width: 110px"
              clearable 
            >
              <el-option
                v-for="item in options"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
            </template>
          </el-table-column>
          <el-table-column prop="project_owner_id" label="负责人" width="120">
            <template #default="{ row }">
              <span v-if="!row.editing && !row.addediting">{{ row.project_owner_id }}</span>
              <el-input
                v-else
                v-model="row.editOwner"
              ></el-input>
            </template>
          </el-table-column>
          <el-table-column prop="project_create_time" label="创建时间" width="320" />
          <el-table-column prop="project_last_mod" label="最后修改时间" width="600" />
          <el-table-column fixed="right" label="Operations" width="240">
            <template #default="{ row, $index }" class="operation_box">
              <el-button size="small" v-if="!row.editing && !row.addediting" @click="handleEdit(row, $index)">Edit</el-button>
              <el-button size="small" type="danger" v-if="row.editing && !row.addediting" @click="handleConfirm(row, $index)">Confirm</el-button>
              <el-button size="small" type="danger" v-if="!row.editing && !row.addediting" @click="handleDelete(row, $index)">Delete</el-button>
              <el-button size="small" v-if="row.editing" @click="handleCancel(row, $index)">Cancel</el-button>
              <el-button size="small" type="danger" v-if="row.addediting" @click="handleaddConfirm(row, $index)">Confirm2</el-button>
              <el-button size="small" v-if="row.addediting" @click="handleaddCancel(row, $index)">Cancel2</el-button>
            </template>
            </el-table-column>
        </el-table>
      </div>
      <div class="pagination">
        <div class="demo-pagination-block">
          <div class="demonstration">每页显示数</div>
          <el-pagination
            v-model:current-page="page"
            v-model:page-size="page_size"
            :page-sizes="[10, 20, 30, 40, 50]"
            :small="small"
            :disabled="disabled"
            :background="background"
            layout="sizes, prev, pager, next"
            :total="total_items"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
  </div>
      </div>
    </div>
  </template>
  
  <script setup>
  import { ref, onMounted } from 'vue';
  import { projectrequest, projectupdate, projectdelete } from '../network/projectrequest';
  
  const projectlist = ref([]);
  const page = ref(1);
  const page_size = ref(10);
  const rowHeight = 40; 
  const small = ref(false);
  const background = ref(false);
  const disabled = ref(false);
  const projectname = ref('');
  const projectowner = ref('');
  const pagination_ctl = ref();
  const total_items = ref();
  const projectrank = ref('');
  const confirmdialog = ref(false);
  const options = [
    {
      value: 'P0',
      label: 'P0',
    },
    {
      value: 'P1',
      label: 'P1',
    },
    {
      value: 'P2',
      label: 'P2',
    },
    {
      value: 'P3',
      label: 'P3',
    },
    {
      value: 'P4',
      label: 'P4',
    },
    {
      value: 'P5',
      label: 'P5',
    },
  ];

  const alert = ref({
  show: false,
  type: 'success',
  title: 'Success alert',
});
function handleAlertClose() {
  alert.value.show = false;
}
  
  onMounted(() => {
    projectinfo(page.value, page_size.value)
  });
  function projectinfo(currentpage,currentpage_size,projectname,projectowner,projectrank){
    projectrequest(currentpage, currentpage_size,projectname,projectowner,projectrank).then((res) => {
      console.log(res.data)
      console.log(res)
      projectlist.value = res.data.data;
      pagination_ctl.value = res.data.pagination;
      total_items.value = pagination_ctl.value['total_items'];
    });
  }

  function handleSizeChange(pagesize_now){
    page_size.value = pagesize_now;
    page.value = 1;
    projectinfo(page.value, page_size.value, projectname.value, projectowner.value, projectrank.value);
  }

  function handleCurrentChange(page_now){
    page.value = page_now
    projectinfo(page.value, page_size.value, projectname.value, projectowner.value, projectrank.value);
  }

  function handleSubmit(currentpage,currentpage_size,projectname,projectowner,projectrank) {
  projectinfo(currentpage,currentpage_size,projectname,projectowner,projectrank);
  projectname = '';
  projectowner = '';
  }

  function handleEdit(row, index) {
  projectlist.value[index].editName = row.project_name;
  projectlist.value[index].editOwner = row.project_owner_id;
  projectlist.value[index].editRank = row.project_rank;
  projectlist.value[index].editing = true;
}

  function handleConfirm(row, index) {
    const editedData = {
    project_id: row.project_id,
    project_name: row.editName,
    project_rank: row.editRank,
    project_owner_id: row.editOwner,
  };
  //  console.log(editedData);
   projectupdate(editedData)
    .then((res) => {
      if (res.data.responsecode === 1000) {
        alert.value.type = 'success';
        alert.value.title = '更新成功';
        alert.value.show = true;
        // console.log(alert.value)
        projectlist.value[index].project_name = row.editName;
        projectlist.value[index].project_owner_id = row.editOwner;
        projectlist.value[index].editing = false;
      } else {
        alert.value.type = 'error';
        alert.value.title = `更新失败: ${res.data.errorMessage}`;
        alert.value.show = true;
        
        console.error('更新失败:', res.data.errorMessage);
      }
    })
    .catch((error) => {
      alert.value.type = 'error';
      alert.value.title = '更新失败';
      alert.value.show = true;

      console.error('更新失败:', error);
    });
}

  function handleCancel(row, index) {
  projectlist.value[index].editing = false;
}

  function handleDelete(row, index){
    confirmdialog.index = row.project_id;
    confirmdialog.value = true;
}

  function confirmDelete(){
    // console.log(confirmdialog.index);
    projectdelete(confirmdialog.index)
      .then((response) => {
      if (response.data.responsecode === 1000) {
        projectlist.value.splice(confirmdialog.index, 1);
        confirmdialog.value = false;
        alert.value.type = 'success';
        alert.value.title = '删除成功';
        alert.value.show = true;
      } else {
        alert.value.type = 'error';
        alert.value.title = `删除失败: ${response.data.data}`;
        alert.value.show = true;
        confirmdialog.value = false;
      }
    })
    .catch((error) => {
      alert.value.type = 'error';
      alert.value.title = `删除失败: ${error}`;
      alert.value.show = true;
      confirmdialog.value = false;
    });
  }

  function handleAdd() {
  projectlist.value.unshift({
    project_name: '',
    project_rank: '',
    project_owner_id: '',
    project_create_time: '',
    project_last_mod: '',
    addediting: true,
  });
}
  function handleaddConfirm(row, index) {
    const newData = {
    project_name: row.editName,
    project_rank: row.editRank,
    project_owner_id: row.editOwner,
  };
  projectupdate(newData)
    .then((res) => {
      if (res.data.responsecode === 1000) {
        alert.value.type = 'success';
        alert.value.title = '添加成功';
        alert.value.show = true;

        projectinfo(page.value, page_size.value);
      } else {
        alert.value.type = 'error';
        alert.value.title = `添加失败: ${res.data.errorMessage}`;
        alert.value.show = true;

        projectlist.value.splice(index, 1);
      }
    })
    .catch((error) => {
      alert.value.type = 'error';
      alert.value.title = `添加失败: ${error}`;
      alert.value.show = true;

      projectlist.value.splice(index, 1);
    });
  }

  function handleaddCancel(row, index) {
    projectlist.value.splice(index, 1);
  }
  </script>
  
  <style scoped>
  .el-alert {
    margin: 20px 0 0;
    z-index: 1000; 
  }
  .el-alert:first-child {
    margin: 0;
  }

  .operation_box {
    position: relative;
  }

  .operation_box .el-button {
    position: absolute;
    margin-top: 10px;
  }

  .operation_box .el-button:nth-child(2) {
    left: 70px; 
  }
  </style>

拆解

查询功能用表单实现,search_box部分,本质上就是用表单获取新参数,然后handleSubmit里面提交给后端,翻页也是类似的原理,获取参数-->传给后端
element本身表格不带增删改功能,主要难点在实现这块
CUD部分实现主要分两块内容:
1.表格切换可输入文本框:
需要从展示数据切换到可输入的文本框的功能有增和改,这块思路是给行(row)加一个状态属性,通过这个状态属性来切换前端展示的组件,具体看project_table_box这块
如下例,如果满足v-if="!row.editing && !row.addediting",那么这里就展示数据,如果不满足,那就变成input

  <el-table-column fixed prop="project_name" label="项目名" width="150">
    <template #default="{ row }">
      <span v-if="!row.editing && !row.addediting">{{ row.project_name }}</span>
      <el-input
        v-else
        v-model="row.editName"
      ></el-input>
    </template>
  </el-table-column>

控制状态切换的按钮放在了operation_box里面,增加功能的按钮为了美观放在了search_box部分
组件响应顺序:点击功能按钮--功能按钮响应函数修改前端--点击confirm--提交数据给后端,根据返回结果来改变前端/点击cancel--只改变前端,不提交数据
2.从当前行获取数据
主要利用了vue3的slot机制,也就是代码里看到的<template #default="{ row, $index }">这玩意,这种子template的作用就是从父template那边获取元素进行渲染,default定义了获取到的这些东西的变量名,在这里,row是当前行的数据,index表示当前行的索引(也就是projectlist这个数组里的索引),operation_box因为是project_table_box里面的子表,所以他的row和project_table_box的row是一样的。我们可以通过编辑row里面的属性来实现功能,或者通过index直接访问projectlist里面对应的数据。
需要注意的是,增加功能为了给用户提供一行可以用来编辑的空表,用projectlist.value.unshift直接在数组的最前面插入了一行空数据,这种插入是前端性质的,不涉及后端交互,又因为是插入在第一位,所以插入完成或者取消后,可以使用projectlist.value.splice(index, 1)从前端删除这条数据,index表示要移除的索引,1代表要移除1条数据
删除功能和增改实现思路差不多,不过把编辑换成了一个弹窗确认,依旧是operation按钮用于切换前端,在弹出来的弹窗上面的按钮才是真正绑定交互函数的按钮

2.png

标签: none

添加新评论