el-table封装popver組件,点击列筛选行数据功能,支持筛选,搜索,排序功能

子组件:

<template>
    <div class="tableTool" ref="tableTool" @click.stop>
        <el-button @click="shengFnc">升序</el-button>
        <el-button @click="jiangFnc">降序</el-button>
        <el-input v-model="keyword" prefix-icon="el-input__icon el-icon-search" type="text" placeholder="搜索"
            @blur="blurFnc"></el-input>
        <div class="select-box">

            <el-checkbox v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
            <el-checkbox-group v-model="checkedList">
                <el-checkbox v-for="(item, index) in CheckboxArr" :label="item.id" :key="index" :value="item.id">
                    <span>{{ item[type] }}</span>
                </el-checkbox>
            </el-checkbox-group>
        </div>
        <div class="bottom">
            <el-button size="mini" @click="$emit('closeTool')">取消</el-button>
            <el-button type="primary" size="mini" @click="save">确认</el-button>
        </div>
    </div>
</template>
<script>
export default {
    name: "tableCol",
    props: {

        ids: {
            type: Array
        },
        type: {
            type: String
        }

    },

    data() {
        return {
            keyword: "",
            checkAll: false,
            checkedList: [],
            options: [],
            isIndeterminate: true,
            allOptions: [],
            CheckboxArr: JSON.parse(localStorage.getItem('CheckboxArr')),
            c: [],
            elementObj: {},
            tableToolelSize: {},
            zishenkuandu: 0
        };
    },
    methods: {
        shengFnc() {
            this.CheckboxArr.sort((a, b) => a.id - b.id);
        },
        jiangFnc() {
            this.CheckboxArr.sort((a, b) => b.id - a.id);
        },
        blurFnc() {
            // console.log(this.keyword);
            if (this.keyword) {
                this.CheckboxArr = this.CheckboxArr.filter(item => {
                    if (this.$props.type == 'date') {
                        return item.date == this.keyword;
                    } else {
                        return item.name == this.keyword;
                    }
                });
            } else {
                this.CheckboxArr = JSON.parse(localStorage.getItem('CheckboxArr'))
            }
        },
        handleCheckAllChange(val) {
            // console.log(val, this.checkedList);
            this.checkedList = val ? this.CheckboxArr.map(item => item.id) : [];
        },
        save() {
            this.c = []
            this.CheckboxArr.forEach(r => {
                this.checkedList.forEach(i => {
                    if (r.id == i) {
                        this.c.push(r)
                    }
                })
            })
            this.$emit("saveSeach", this.c);
        },


    },
    mounted() {
        // console.log(this.CheckboxArr, JSON.parse(this.$props.elementPosition), "传入的数据");
        this.checkedList = [...this.$props.ids]
        if (this.CheckboxArr.length == this.checkedList.length) {
            this.checkAll = true
        } else {
            this.checkAll = false
        }

    },

};
</script>

<style scoped>
.tableTool {
    /* position: fixed; */
    background: #fff;
    box-shadow: 0 0 5px #ccc;
    padding: 10px;
    z-index: 999;


}

/deep/.el-input__inner {
    padding-left: 30px;
}

.select-box {
    border: #ccc solid 1px;
    padding: 10px;
    margin-top: 10px;
    max-height: 280px;
    overflow: auto;
    max-width: 400px;
}

/deep/ .el-checkbox {
    display: block;
    margin-top: 5px;
}

/deep/ .el-radio-group {
    display: flex;
    flex-direction: column;
}

.bottom {
    display: flex;
    justify-content: flex-end;
    margin-top: 10px;
}


.el-checkbox:last-of-type {
    margin-right: none;
}
</style>

父组件:

<template>
  <div class="home">
    <!-- <img alt="Vue logo" src="../assets/logo.png">
      <HelloWorld msg="Welcome to Your Vue.js App" /> -->
    <el-button @click="dialogVisible = true">求和</el-button>
    <el-input v-model="searchValue"></el-input>
    <el-steps :active="3" simple>
      <el-step title="步骤 1" icon="el-icon-edit"></el-step>
      <el-step title="步骤 2" icon="el-icon-upload"></el-step>
      <el-step title="步骤 3" icon="el-icon-picture"></el-step>
    </el-steps>

    <el-table :data="tableData" height="250" border style="width: 100%;position: relative;" id="table1">

      <el-table-column prop="date" label="日期" width="180" align="center">
        <template v-slot:header>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'date')">
          </div>
          <span class="table-heard-filter" style="color: red; font-weight: bold;">0</span>
        </template>

      </el-table-column>
      <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column> <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column> <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column> <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column> <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column> <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column> <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column> <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column> <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column> <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column> <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column> <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column> <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column> <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column> <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column> <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column> <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column> <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column> <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column> <el-table-column prop="name" label="姓名" width="120" align="center">
        <template v-slot:header>
          <el-checkbox v-model="checked2" style="float: left;"></el-checkbox>
          <div style="width: 20px;height: 20px;background: rebeccapurple;float: right;"
            @click.stop="filterData($event, 'name')">
          </div>
          <span class="table-heard-filter">1</span>
        </template>

      </el-table-column>
    </el-table>
    <div v-if="showFilterTool" ref="popover" class="popover" :style="popoverStyle" style="position: absolute;">

      <TableTool ref="selectTool" @closeTool="closeTool" @saveSeach="saveSeach" :ids="ids" :type="type" />
    </div>
    <i v-if="showFilterTool" class="el-icon-caret-top" :style="{ left: a + 'px', top: b + 20 + 'px' }"
      style="position: absolute;"></i>

    <el-dialog title="提示" :visible.sync="dialogVisible" width="30%">
      <span slot="footer" class="dialog-footer">
        <span>{{ form.address }}</span>
        <span>{{ form.name }}</span>
        <span>{{ form.password }}</span>
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
        <el-button type="primary" @click="share(form)">复制</el-button>
        <el-button type="primary"
          @click="printFnc('https://inews.gtimg.com/om_bt/OGlQWfsaAoKkuCcMZ2o9IVEPqd-72DQy5EAN02XBHUwfYAA/641', 'jpeg')">打印</el-button>
      </span>
    </el-dialog>
    <div style="width: 200px;height: 20px;background: rebeccapurple;position: fixed;top: 20px;left:20px"
      ref="pageContainer" @click="filterData">
    </div>
  </div>
</template>

<script>
import HelloWorld from '@/components/HelloWorld.vue'
import TableTool from '@/components/TableTool.vue'
import ColumnDialog from './ColumnDialog.vue'
import { Checkbox } from 'element-ui';
import watermark from '@/utils/watermark.js'
import printJS from 'print-js'
export default {
  name: 'HomeView',
  components: {
    HelloWorld,
    TableTool,
    ColumnDialog
  },
  computed: {
    popoverStyle() {
      return {
        left: this.popoverPosition.left + 'px',
        top: this.popoverPosition.top + 14 + 'px',
      };
    },
  },
  data() {
    return {
      a: "",
      b: "",
      popoverPosition: { left: 0, top: 0 },
      form: {
        address: "https://www.baidu.com/", // 地址信息
        name: "张三",
        password: "123",
      },
      isShow: false,
      dialogVisible: false,
      checked: false,
      checked2: false,
      summaryShow: false,
      summary: [],  // 用于存放总计数据的数组
      searchValue: "",
      CheckboxArr: [],
      ids: [], // 初始化ids为空数组
      type: "",
      currentSummaryColumn: null, // 当前点击的列名
      tableData: [{
        date: '2016-05-03',
        name: 56,
        address: 8,
        id: "0"
      }, {
        date: '2016-05-02',
        name: 78,
        address: 8,
        id: "1"
      }, {
        date: '2016-05-04',
        name: 0,
        address: 8,
        id: "2"
      }

      ],
      showFilterTool: false,
      CheckboxArr: [],
      ids: [],
      type: "",
      currentSummaryColumn: null // 当前点击的列名
    }
  },
  mounted() {
    localStorage.setItem('CheckboxArr', JSON.stringify(this.tableData))
    this.closeTableToolFnc()
    //添加水印
    // console.log(this.$refs.pageContainer);
    // watermark.set('1234567', '谁在花里胡哨', this.$refs.pageContainer)


  },
  beforeDestroy() {
    this.closeTableToolFnc()
  },
  methods: {
    // 判断是否是 IE 浏览器
    isIE() {
      if (window.ActiveXObject || "ActiveXObject" in window) {
        return true;
      } else {
        return false;
      }
    },
    share(url) {
      if (this.isIE()) {

        this.$copyText(this.form.password);
        // this.$refs.addressInput.select(); // 实现选中效果
        this.$message.success("复制成功!");
      } else {

        let obj = {
          '地址': this.form.address,
          '用户名': this.form.name,
          '密码': this.form.password
        }
        const objectString = JSON.stringify(obj);
        this.$copyText(objectString)
          .then((res) => {
            // this.$refs.addressInput.select(); // 实现选中效果
            this.$message.success("复制成功!");
          })
          .catch((err) => {
            this.$message.error("该浏览器不支持自动复制, 请手动复制");
          })
      }
    },
    printFnc(url, filetype) {
      let path = url
      let type = ''
      const acceptedFileTypes = ['png', 'jpeg', 'jpg', 'gif'];
      console.log(acceptedFileTypes.includes(filetype));
      if (acceptedFileTypes.includes(filetype)) {
        type = 'image'
      } else {
        type = filetype
      }
      printJS({
        printable: path,
        type: type,
        // showModal: true,//开启加载modal
        onErrorL: (err) => {
          return this.$message({
            type: "error",
            message: '打印失败,请检查打印机设置或尝试保存文件!'

          })
        }
      })
    },
    //子组件只用@click.stop防止事件冒泡,父组件单击任意位置关闭子组件
    closeTableToolFnc() {
      document.addEventListener("click", (e) => {
        this.closeTool()
      });
    },
    filterData(e, type) {
      this.type = type
      this.showFilterTool = true;
      this.$nextTick(() => {
        const buttonRect = e.target.getBoundingClientRect();
        const popoverRect = this.$refs.popover.getBoundingClientRect();
        this.a = buttonRect.left
        this.b = buttonRect.top
        console.log(buttonRect.left);

        let leftPosition = buttonRect.left - (popoverRect.width - buttonRect.width) / 2;

        // 调整popover位置,防止超出可视范围
        if (leftPosition < 0) {
          leftPosition = 10;
        } else if (leftPosition + popoverRect.width > window.innerWidth) {
          leftPosition = window.innerWidth - popoverRect.width - 10;
        }


        this.popoverPosition = {
          left: leftPosition,
          top: buttonRect.bottom,
        };
        this.ids = []
        this.tableData.forEach(t => {
          this.ids.push(t.id)
        })
        this.showFilterTool = true;

      });
    },
    closeTool() {
      this.showFilterTool = false;
    },

    saveSeach(data) {
      this.tableData = []
      this.tableData = data
      this.closeTool();
    },
  }

}
</script>
<style>
.Tableone ::-webkit-scrollbar,
::-webkit-scrollbar-track,
::-webkit-scrollbar-thumb {
  display: none
}

.el-icon-caret-top {
  /* position: absolute; */
  color: #999;
  /* top: -13px; */
  font-size: 20px;

}
</style>

效果:

  • 25
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了实现点击el-input出现el-popover,并且使el-popover始终出现在el-input下方,可以按照以下步骤进操作: 1. 在el-input标签中添加ref属性,用于在JavaScript中引用该元素。 2. 在el-input标签中添加@click事件,用于在单击el-input时触发JavaScript函数。 3. 在JavaScript函数中,使用this.$refs获取el-input元素的位置信息,并计算出el-popover应该出现的位置。 4. 在el-popover标签中添加v-model属性,用于控制el-popover的显示和隐藏。 5. 在el-popover标签中添加popper-class属性,用于自定义el-popover的样式。 6. 在el-popover标签中添加transition属性,用于设置el-popover的过渡效果。 下面是一个示例代码,可以实现点击el-input出现el-popover,并且使el-popover始终出现在el-input下方: ```html <template> <div> <el-input ref="input" v-model="inputValue" placeholder="请输入内容" @click="showPopover"></el-input> <el-popover v-model="popoverVisible" popper-class="my-popover" transition="el-fade-in-linear"> <div>这是一个el-popover</div> </el-popover> </div> </template> <script> export default { data() { return { inputValue: '', popoverVisible: false } }, methods: { showPopover() { this.popoverVisible = true; this.$nextTick(() => { const inputRect = this.$refs.input.getBoundingClientRect(); const popoverRect = this.$refs.popover.$el.getBoundingClientRect(); const top = inputRect.top + inputRect.height; const left = inputRect.left + inputRect.width / 2 - popoverRect.width / 2; this.$refs.popover.$el.style.top = `${top}px`; this.$refs.popover.$el.style.left = `${left}px`; }); } } } </script> <style> .my-popover { background-color: #f0f0f0; color: #333; border: none; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); } </style> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值