1. 程式人生 > >【Vue】element表格巢狀內容點選展開、收起一行

【Vue】element表格巢狀內容點選展開、收起一行

需求如下:新增一個需求時,除了填寫一些公共資訊,例如名稱、負責人、所屬專案等,還可將一個需求分解為多個模組以及評估人員(如下圖)。儲存後在列表頁展示需求的公共欄位資訊,點選某條需求時,展開該需求下的模組以及評估人員等資訊。

程式碼如下,有去除部分無關的程式碼。首先宣告這裡的展開行資料是每次點選某行去後臺請求返回的,也可以一次性直接返回所有資料。要實現該功能,重點都在外層table上的這幾個屬性和事件:row-click、expand-change、row-key、expand-row-keys。核心思想是:保證點選某一行的時候,expand-row-keys中有且僅有該行的id,要收起該行時,清空expand-row-keys中的值。

<template>
  <div>
    <div style="float: left">
      <el-input placeholder="需求名稱/所屬專案搜尋" v-model="input4" style="width: 368px">
        <template slot="append" ><el-button slot="append" icon="el-icon-search" @click="getmainTableList()"></el-button></template>
      </el-input>
    </div>
    <div class="btn-style">
      <el-button type="primary" @click="requirementForm('')">新增需求</el-button>
    </div>

    <div class="head-div">
      <el-button class="btn-div"  @click="deleteAll()" :disabled="!allowDisplay">批量刪除</el-button>
    </div>
    <el-table :data="tableData5" style="width: 100%" border @select="selectChange" @select-all="selectChange" ref="table"
              @row-click="expandChange" :row-key="getRowKeys" :expand-row-keys="expands" @expand-change="expandChange">
      <el-table-column type="expand">
        <template slot-scope="props">
          <el-table :data="tableData" border style="width: 100%">
            <el-table-column prop="moduleName" label="涉及模組" width="180"></el-table-column>
            <el-table-column prop="evaluatorName" label="評估人員" width="180"></el-table-column>
            <el-table-column prop="state" label="狀態"></el-table-column>
            <el-table-column label="操作">
              <template slot-scope="scope">
             
              </template>
            </el-table-column>
          </el-table>
        </template>
      </el-table-column>
      <el-table-column type="selection" width="55"></el-table-column>
      <el-table-column label="需求id" prop="id" v-if="false"></el-table-column>
      <el-table-column label="需求名稱" prop="name"></el-table-column>
      <el-table-column label="所屬專案" prop="projectName"></el-table-column>
      <el-table-column label="建立人員" prop="createdByName"></el-table-column>
      <el-table-column label="負責人" prop="chargeByName"></el-table-column>
      <el-table-column label="狀態" >
        <template slot-scope="scope">
          {{$t(scope.row.state)}}
        </template>
      </el-table-column>
      <el-table-column label="操作">
        <template slot-scope="scope">
          <el-button type="text" @click="deleteBatch(scope.row.id)">刪除</el-button>
          <el-button type="text" @click="requirementForm(scope.row.id)" v-if="scope.row.state !== 'terminated'">編輯</el-button>
        </template>
      </el-table-column>
    </el-table>
    <div class="f-tar">
      <table-bar :total="total" table="table" @change="getList" :checkbox="false">
      </table-bar>
    </div>
  </div>
</template>
<script>
  import tableOperation from '@/components/layout/tableOperation'
  import  * as api from '@/api/ptms'
  import {tips} from '../../static/js/global.js'
  let moment = require("moment");
  import TableBar from '@/components/TableBar'
  export default {
    components:{ TableBar},
    data() {
      return {
        allowDisplay:false,//批量刪除、批量指派顯示
        input4:'',
        table: [],
        total: 0,//資料的總條數
        tableData5: [
        ],
        tableData: [
        ],
        dataIds: [],
        param:{
          // limit: 10,
          limit: Number.parseInt(localStorage.getItem('currentSize') || 10),
          skip: 0,
          name: ""
        },
        actor: '張俊', // TODO 直接取的登入使用者資訊
        // 獲取row的key值
        getRowKeys(row) {
          return row.id;
        },
        expands: [],
      }
    },

    created(){
      this.setData();
    },

    methods:{

      // 初始化
      setData(){
        this.findPagesByCondition(this.param);
      },

      // 條件查詢
      getmainTableList(){
        this.param.name = this.input4;
        this.findPagesByCondition(this.param);
      },

      //分頁
      getList(assign){
        console.log(assign)
        this.param.name = this.input4;
        if (assign instanceof Object) {
          const object2 = Object.assign(this.param, assign)
          this.findPagesByCondition(object2);
        }
      },

      findPagesByCondition(param){
        api.getListRequirement(param)
          .then((res)=>{
            if(res.ret > -1){
              console.log(res.data)
              this.total = res.data.total;
              this.tableData5 = res.data.data;
              this.expands = [];
              // this.param.limit = res.data.data;
              // this.param.skip = res.data.data;
            }
          });
      },

      //批量刪除、批量指派-多選計算
      selectChange(selection) {
        this.allowDisplay = selection.length > 0;
        if(this.allowDisplay){
          this.dataIds = selection.map((item) => item.id);
        }else{
          this.dataIds = [];
        }
      },

      //批量刪除
      deleteAll(){
        this.deleteBatch(this.dataIds)
      },

      // 檢視指派評估詳情
      expandChange(row) {
        let temp = this.expands;
        this.expands = [];
        this.expands.push(row.id);
        if(temp.length === 1 && temp[0] === row.id){     // 收起展開行
          this.expands = [];
        }else {
          api.viewRequirementModuleOrg({requirementId: row.id})
            .then((res)=>{
              if(res.ret > -1){
                res.data.data.map(x=>{
                  x.state=this.$t(x.state);
                });
                this.tableData = res.data.data;
              }
            })
        }

      },

      // 新增、編輯需求頁面跳轉
      requirementForm (id){
        if(id !== ''){
          this.$router.push({ path: `/requirementForm/${id}`});
        }else {
          this.$router.push({ path: '/requirementForm'});
        }
      },

      // 刪除及批量刪除
      deleteBatch(val){
        const arr = [];
        if(typeof val === 'object'){
          for(let i=0; i<val.length; i++){
            arr.push(val[i]);
          }
          this.deleteAction('確認刪除這'+ val.length +'個需求?' + '可能造成相應任務的刪除', arr);
        }else {
          arr.push(val);
          this.deleteAction("確認刪除該需求?" + '可能造成相應需求及任務的刪除', arr);
        }
      },

      deleteAction(content, arr) {
        this.$confirm(content, '提示', {
          confirmButtonText: '確定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          api.requirementDelete({id: arr})
            .then((res)=>{
              if(res.ret === 0){
                tips(this, '刪除成功!', 'success');
                this.setData();
                this.allowDisplay = false;
              }
            })
        }).catch(() =>{
          // 取消
        });
      },

    },
  }
</script>
<style lang="scss" scoped>
  .demo-table-expand {
    font-size: 0;
  }
  .demo-table-expand label {
    width: 90px;
    color: #99a9bf;
  }
  .demo-table-expand .el-form-item {
    margin-right: 0;
    margin-bottom: 0;
    width: 50%;
  }
  .btn-style{
    float: right;
    margin-top:-20px;
    padding: 15px;
  }
  .demo-table-expand {
    font-size: 0;
  }
  .demo-table-expand label {
    width: 90px;
    color: #99a9bf;
  }
  .demo-table-expand .el-form-item {
    margin-right: 0;
    margin-bottom: 0;
    width: 50%;
  }
  .f-tar {
    text-align: right;
  }
  .head-div{
    border-right: 1px solid #ebeef5;
    border-top: 1px solid #ebeef5;
    border-left: 1px solid #ebeef5;
    width: 100%;
    height: 60px;
    clear: both;
  }
  .btn-div{
    margin-top: 10px;
    margin-left: 20px;
  }
</style>

下面附上element官網對這幾個屬性事件的說明: