el-table 多选 选中数据动态回显

实现后的效果:

el-table 多选 选中数据动态回显_第1张图片

需求

表格展示数据,选中的数据展示在表格下方,点击删除图标删除选中的数据,需要同步到table中更新选中状态

index.vue

<template>
  <div>
   <el-button  @click="handleClick()" > 按钮</el-button>
   <table-dialog ref="tableDialog " :wildAxios="wildAxios" @callback="handleCallback">
   </table-dialog>
  </div>
</template>
<script>
	import { Button } from 'element-ui'
	import TableDialog from './table-dialog'
	export default {
	  components: {
	    [Button.name]: Button,
	    TableDialog
	  },
	  data(){
	  return{
	  }
	  },
	  methods:{
		showBox() {
		  let showData = [
		  { id:1, name:"name1" },
          { id:2, name:"name2" },
          ]
         this.$refs.tableDialog .show(showData)
      },
      handleCallback(selectData){
        console.log(selectData)
      }
	}
  }
  </script>

table-dialog.vue

<template>
  <el-dialog
    top="2vh"
    width="800px"
    :show-close="false"
    :visible.sync="dialogVisible"
    :close-on-click-modal="false"
    class="page-dialog"
  >
  <div class="dialog-header">
    <div class="title">这里是弹框标题</div>
    <div class="header-btns">
      <el-button size="mini" @click="handleClose">取 消</el-button>
      <el-button size="mini" type="primary" @click="handleSubmit">确 定</el-button>
    </div>
  </div>
  <div class="dialog-body">
    <div class="search">
      <el-input size="small" v-model="keyword" placeholder="请输入关键字" :style="{ width: '200px' }"></el-input>
      <el-button size="small" @click="handleSearch">搜索</el-button>
    </div>
    <el-table 
      ref="table"
      row-key="id"
      :data="tableData" 
      style="width: 100%" height="360px" size="small" 
      @select="handleTableSelect"
      @select-all="handleTableSelectAll"
      >
      <el-table-column
        label="全选"
        type="selection"
        width="55">
      </el-table-column>
      <el-table-column prop="id" label="id"></el-table-column>
      <el-table-column prop="name" label="名称"></el-table-column>
    </el-table>
  </div>
  <div class="dialog-footer">
    <div v-for="(item,index) of selectData" :key="index" class="select-item">
      <span class="title">{{item.name}}</span>
      <i class="el-icon-delete" @click="handleSelectDataDel(item.id)"></i>
    </div>
  </div>
  </el-dialog>
</template>

<script>
import { Dialog, Button, Table, TableColumn, Input } from 'element-ui'
export default {
  components: {
    [Dialog.name]: Dialog,
    [Button.name]: Button,
    [Input.name]: Input,
    [Table.name]: Table,
    [TableColumn.name]: TableColumn,
  },
  data() {
    return {
      dialogVisible: false,
      keyword:"",
      tableData:[],
      selectData: [], // 当前选中的数据
      dates:[
        { label: "最近7天", value: 7 },
        { label: "最近15天", value: 15 },
        { label: "最近30天", value: 30 },
      ]
    };
  },
  methods: {
    // 初始化弹窗
    show(showData){
      this.dialogVisible = true
      this.selectData = showData
      // showData 是初始数据的回显
      const params = {}
      this.getData(params)
    },
      // 查询历史流程
    getData(params) {
      // todo 这里调用接口 params 为接口参数
      this.tableData = [
        { id:1, name:"name1" },
        { id:2, name:"name2" },
        { id:3, name:"name3" },
        { id:4, name:"name4" },
        { id:5, name:"name5" },
        { id:6, name:"name6" },
      ]
      // 接口返回后执行 table 数据回显api
       this.setCurrentRow(this.showData)
    },
    
    // 数据过滤
    handleSearch() {
      let params = {keyword:this.keyword}
      this.getData(params)
    },
    /*
     这里之所以用这两个方法,而不是 selection-change api 是因为 在执行删除图标 进行数据删除操作时,
     selection-change 会被多次执行
    */
    // table 单选
    handleTableSelect(data,row){
      this.selectData = data
    },
    // table 全选
    handleTableSelectAll(data){
      this.selectData = data
    },
    // 数据删除
    handleSelectDataDel(id){
      this.selectData = this.selectData.filter(item=>item.id !== id)
      this.setCurrentRow(this.selectData)
    },
    // table 选项勾选状态设置
    setCurrentRow(selectData){
      this.$nextTick(() => {
        // 先清除所有的勾选,然后重新设置数据勾选的状态
        this.$refs.table.clearSelection()
        if(!selectData || selectData.length === 0) return
        selectData.forEach(item=>{
          const index = this.getIndex(item.id)
          if(index === -1) return
          //注意: 这里需要用 table 原来绑定的数据对象 作为回显函数的参数才能正确勾选
          this.$refs.table.toggleRowSelection(this.tableData[index], true);
        })
      })
    },
    // 获取table 数据中的下标
    getIndex(selectDataId){
      let index = -1
      for(let i=0;i<this.tableData.length;i++){
        const item = this.tableData[i]
        if(item.id === selectDataId){
          index = i
          continue
        }
      }
      return index
    },
    // 关闭弹窗
    handleClose(){
      this.dialogVisible = false
      this.keyword = "",
      this.tableData = [],
      this.selectData = []
    },
    // 确定按钮
    handleSubmit(){
      this.$emit('callback',this.selectData)
      this.handleClose()
    }
  },
};
</script>
<style lang="scss" scoped>
.page-dialog{
 .dialog-header{
   padding: 0 20px;
   display: flex;
   border-bottom: 1px solid #EBEEF5;
   justify-content: space-between;
   .title{
     font-size: 16px;
     .subheading{
     font-size: 14px;
       color: #767676;
     }
   }
  }
  .dialog-body{
    overflow: hidden;
    border-bottom: 1px solid #EBEEF5;
    height: 400px;
    position: relative;
    .search{
      padding-top: 10px;
      display: flex;
      text-align: right;
      justify-content: flex-end;
     .el-select,
     .el-input,
     .el-button{
        margin-right: 10px;
      }
    }
  }
  .dialog-footer{
    padding: 10px;
    overflow: auto;
    max-height: 100px;
    font-size: 12px;
    .select-item{
      margin: 4px 0;
      .title{
        padding: 0 4px;
        margin-right: 10px;
        width: calc(100% - 40px);
        display: inline-block;
        background-color: #f9f9f9;
      }
      .el-icon-delete{
        cursor: pointer;
      }
    }
  }
}
</style>
<style lang="scss">
// 修改dialog 原来的样式
.page-dialog{
  .el-dialog__body{
    padding: 0 !important;
  }
  .el-dialog__header{
    padding: 0 !important;
    padding-bottom: 10px !important;
  }
}
</style>

你可能感兴趣的:(前端VUE项目,js,vue,js)