vue2 table 表格动态列设置

<template>
  <div class="elian--table-field">
    <div class="elian--table-field-left">
      <div class="elian--table-field-title">
        <div class="title-left">
          <span>全部字段</span>
          <span>({{dataLen}})</span>
        </div>
        <div class="title-right title-hover">
          <span clss="fs14" @click="handleCheckAll">全选</span>
        </div>
      </div>
      <div class="elian--table-field-list p12 bb b-c b-r-10">
        <div class="elian--table-field-list-item" v-for="(item,index) in dataList" :key="index">
          <el-checkbox v-model="item[check]" @change="handlecheckItem(item,index)">{{item[label]}}</el-checkbox>
        </div>
      </div>
    </div>
    <div class="elian--table-field-center">
      <i class="el-icon-arrow-right fs22" />
    </div>
    <div class="elian--table-field-right">
      <div class="elian--table-field-title">
        <div class="title-left">
          <span>已选字段</span>
          <span>({{ checkLen + "/" + dataLen}})</span>
        </div>
        <div class="title-right title-hover">
          <span clss="fs14" @click="handleClear">清空</span>
        </div>
      </div>
      <div class="elian--table-field-list p12 bb b-c b-r-10">
        <Draggable v-model="checkDataList" @change="handleChange" @start="handleStart" class="grid-container"
          @end="handleEnd" :options="{ handle: '.drag-handle' }">
          <div class="elian--table-field-list-item list-item" v-for="(item,index) in checkDataList" :key="index">
            <!-- <i class="el-icon-rank fs16 title-hover drag-handle" /> -->
            <img src="@/assets/imgs/drag_icon.png" alt="" class="drag-handle">
            <span class="fs14 list-item-title">{{item[label]}}</span>
            <i class="el-icon-close fs16 m-l title-hover" @click="handleDel(item,index)" />
          </div>
        </Draggable>
      </div>
    </div>

    <div class="elian--table-field-footer">
      <div class="fs14 footer-left " @click="handleDefaultSet">
        <span class="title-hover">恢复默认设置</span>
        <div class="footer-tips">
          <img class="img6" src="@/assets/imgs/tips_icon.png" alt="">
          <span class="fs12 c5">清理浏览器缓存将恢复默认设置</span>
        </div>
      </div>
      <div>
        <el-button type="primary" plain size="mini" @click="handleClose">取消</el-button>
        <el-button type="primary" size="mini" @click="handleSave">保存</el-button>
      </div>
    </div>
  </div>
</template>

<script>
import Draggable from 'vuedraggable'
import cryptoJS from "crypto-js"
export default {
  name: 'TableFieldSet',
  components: {
    Draggable
  },
  props: {
    data: {
      type: Array,
      default: () => []
    },
    value: {
      type: String,
      default: 'value'
    },
    label: {
      type: String,
      default: 'label'
    },
    check: {
      type: String,
      default: 'visible'
    },
    active: {
      type: Array,
      default: () => []
    },
    keys: {
      type: String,
      default: ''
    },
    table:{
      type:String,
      default: 'tableRef'
    }
  },
  data() {
    return {
      dataList: [],
      checkDataList: [],
      isChange:false,
    };
  },
  created() {

  },
  mounted() {

  },
  methods: {
    handleCheckAll() {
      this.dataList.forEach(item => { item[this.check] = true })
      this.checkDataList = [...this.dataList]
      // const isAllChecked = this.dataList.every(item => item.checkbox)
      // this.dataList.forEach(item => {
      //   item.checkbox = isAllChecked ? false : true
      // })
      // if (isAllChecked) this.checkDataList = []
      // else this.checkDataList = [...this.dataList]
    },
    // 清空
    handleClear() {
      this.checkDataList = []
      this.dataList.forEach(item => { item[this.check] = false })
    },
    handlecheckItem(item, index) {
      this.dataList[index][this.check] = item[this.check]
      this.$forceUpdate()
      let findIndex = this.checkDataList.findIndex(items => items[this.value] == item[this.value])
      if (item[this.check] && findIndex < 0) {
        this.checkDataList.push(item)
      } else {
        this.checkDataList.splice(findIndex, 1)
      }
    },
    handleMoveRight() {
      let arr = this.dataList.filter(item => item[this.check])
      this.checkDataList = arr
    },
    handleDel(item, index) {
      this.checkDataList = this.checkDataList.filter(items => items[this.value] != item[this.value])
      let findIndex = this.dataList.findIndex(items => item[this.value] == items[this.value])
      this.$set(this.dataList, findIndex, { ...item, [this.check]: false })
    },

    handleDefaultSet() {
      let { dataList, checkDataList } = this.initDataList(this.active)
      this.dataList = dataList
      this.checkDataList = checkDataList
    },

    handleClose() {
      this.$emit('update:visible', false)
    },
    handleSave() {
      // console.log("com ELianTableFieldSet save", this.keys)
      if (this.checkDataList.length == 0) return this.$message.warning("请选择要显示的字段信息")

      let data = {
        checkData: this.checkDataList,
        allData: this.dataList,
        keys: this.keys
      }
      let keys = cryptoJS.MD5(this.keys).toString()
      localStorage.setItem(keys, JSON.stringify(this.checkDataList))
      this.$emit('update:active', this.checkDataList)
      this.$emit('update:visible', false)
      this.$emit('save', data,this.isChange)
       console.log("this.$refs.list", this.$parent.$refs[this.table])
      if(this.isChange){

      }
      console.log("com ELianTableFieldSet save",this.$parent)
      this.$eventBus.$emit('nextTickRefreshTable')
    },
    handleChange(e) {
      this.isChange = true
      console.log('com ELianTableFieldSet handleChange',e)
    },
    handleStart(e) {
      console.log('com ELianTableFieldSet handleStart',e)

    },
    handleEnd(e) {
      console.log('com ELianTableFieldSet handleEnd',e)
    },

    initDataList(active) {
      let newValList = active.map(item => item[this.value])
      let tData = JSON.parse(JSON.stringify(this.data))
      let tActive = JSON.parse(JSON.stringify(active))
      tData = tData.map(item => {
        if (newValList.includes(item[this.value])) {
          return { ...item, [this.check]: true }
        } else {
          return { ...item, [this.check]: false }
        }
      })
      return {
        dataList: tData,
        checkDataList: tActive
      }
    }
  },
  computed: {
    checkLen() {
      return this.checkDataList.length || 0
    },
    dataLen() {
      return this.data.length || 0
    }
  },
  watch: {
    active: {
      handler(newVal, oldVal) {
        if (newVal) {
          let { dataList, checkDataList } = this.initDataList(newVal)
          this.dataList = dataList
          this.checkDataList = checkDataList
        } else {
          this.dataList = this.data.map(item => ({ ...item, [this.check]: false }))
        }
      },
      immediate: true
    }
  },
};
</script>

<style scoped lang="scss">
.elian--table-field {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;

  .elian--table-field-left,
  .elian--table-field-right {
    width: 36%;
    flex: 1;

    .elian--table-field-title {
      margin: 10px 0;
      display: flex;
      justify-content: space-between;
      cursor: pointer;
      padding: 0 2px;
    }
  }
  .elian--table-field-center {
    width: 4%;
    text-align: center;
    .el-icon-arrow-right {
      cursor: pointer;
    }
  }
  .elian--table-field-footer {
    width: 100%;
    height: 52px;
    display: flex;
    justify-content: space-between;
    align-items: center;

    .footer-left {
      display: flex;
      align-items: center;
    }
    .footer-tips {
      display: flex;
      margin-left: 20px;
    }
  }

  .elian--table-field-list {
    padding: 12px;
    box-sizing: border-box;
    min-height: 530px;
    max-height: 550px;
    overflow: auto;

    .elian--table-field-list-item {
      margin-bottom: 5px;
      display: flex;
      align-items: center;

      .list-item-title {
        margin-left: 5px;
      }
    }
    .list-item {
      padding: 2px 0;
    }
  }
}

.title-hover:hover {
  color: #409eff;
  cursor: pointer;
}

/* 拖拽选中时的颜色 */
.sortable-chosen {
  background-color: #409eff !important; /* 浅蓝色 */
  border: 1px dashed #1890ff; /* 加个虚线边框 */
}

/* 拖拽中的元素 */
.sortable-drag {
  opacity: 0;
  background-color: #409eff !important;
}
.drag-handle{
  width:13px;
}
</style>
使用方式:
  <TableFieldSet  :visible.sync="isShowSetDialog" :data="fieldsData"
        :active.sync="currentFieldsActive" :check="fieldsCheck" :value="fieldsValue" :label="fieldsLabel"
        :keys="fieldsKey" @save="handleSave" table="tableRef" />
需要安装 
 'vuedraggable' 和 "crypto-js"(可选)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值