elementUI + vue实现 Excel筛选功能

2023-11-07

element仿照EXCEL
和后端交互数据联动筛选
公司要el-table基础上实现一个excel的功能,element的不能满足我的需求于是自己写了一个。

tableTool.vue组件实现

组件介绍:组件为筛选框,配合element中el-table使用
使用示例:
<i class="el-icon-caret-bottom" @click="filterData($event,'date')"></i>
<tableTool v-if="showFilterTool" ref="tableTool" :seachData="seachData" @saveSeach="saveSeach" :allOptionsObj="allOptionsObj" :seachType="seachType" :filterToolLeft="filterToolLeft" :filterToolTop="filterToolTop" @closeTool="closeTool" />
在父组件中请使用showFilterTool来控制tableTool,父组件给一个控件添加点击事件,拿到点击事件的位置及需要处理的数据是属于哪一个方法如下:
  filterData(e,type){
        this.showFilterTool = false       //点击区域控件触发时可以关闭当前的筛选框
        this.$nextTick(()=>{
            this.seachType = type
            this.filterToolTop = e.pageY   //拿到小工具的位置
            this.filterToolLeft = e.pageX  //拿到小工具的位置
            this.showFilterTool = true
        })
    },
    seachData:查询结果数据,可以让父级传过来进行回填注意数据结构应该为{ key:[],key1:[],....}
    seachData:{
            name:[],
            address:[],
            date:[],
        }
    allOptionsObj:所有的可查询条件,数据结构和seachData一样,并且key值一样
    allOptionsObj:{
            name:['王小虎','小明','小红','小兰'],
            address:['北京','上海','广州','深圳','长沙'],
            date:['2016','2017','2018','2019'],
    },
    seachType:需要查询的key(seachData的key中的一个)
    seachType:'name' //默认
    filterToolTop、filterToolLeft:拿到点击控件的位置得到的传入数值即可
    filterToolTop:0, filterToolLeft:0,
    saveSeach:点击确认向父组件发送的事件,用于将筛选的结果传给父级
    saveSeach(data){
        console.log(data);
        this.seachData = data
        this.closeTool()
    },
    closeTool:点击取消向父级发送的事件。
    closeTool(){
        this.showFilterTool = false
    },
<template>

    <div class="tableTool" :style="{top:filterToolTop + 10 +'px',left:filterToolLeft +'px'}">
        <el-input v-model="keyword" prefix-icon="el-input__icon el-icon-search"  type="text" placeholder="搜索" @input="seachKey"  oninput="if(value.length>11)value=value.slice(0,100)">
        </el-input>
       <div class="select-box">
            <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange" id="checkAll">全选</el-checkbox>
            <el-checkbox-group v-model="checkedList" @change="handleCheckedCitiesChange">
                <el-checkbox v-for="(item,index) in options" :label="item" :key="index">
                </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>
       <i class="el-icon-caret-top"></i>
    </div>
</template>
<script>
  export default {
    name:'tableCol',
    props:{
        filterToolLeft:{
            required:true,
            type:Number
        },
        filterToolTop:{
            required:true,
            type:Number
        },
        // 已经选中的数据
        seachData:{
            required:true,
            type:Object
        },
        // 正在更改哪个
        seachType:{
            required:true,
            type:String
        },
        // 需要后端给的所有数据
        allOptionsObj:{
            required:true,
            type:Object
        },
        useTableToolComponent:{
            default:null
        }
    },
    data() {
      return {
        keyword:'',
        checkAll: false,
        checkedList: [],
        options: [],
        isIndeterminate: true,
        allOptions:[]
      };
    },
    methods: {
      handleCheckAllChange(val) {
        this.checkedList = val ? this.allOptions : [];
        this.isIndeterminate = false;
      },
      handleCheckedCitiesChange(value) {
        let checkedCount = value.length;
        this.checkAll = checkedCount === this.options.length;
        this.isIndeterminate = checkedCount > 0 && checkedCount < this.options.length;
      },
      save(){
          this.seachData[this.seachType] = this.checkedList
          //  把查询条件给父组件 
          this.$emit('saveSeach',this.seachData)
      },
      seachKey(){
          this.allOptions = this.allOptionsObj[this.seachType].filter(item=>item.indexOf(this.keyword)!= -1)
          this.options = this.allOptions 
          this.checkedList = []
          this.checkAll = false
      },
      setposition(){
        let boxEl = document.querySelector('.tableTool')
        let icon = document.querySelector('.tableTool .el-icon-caret-top')
        if(this.filterToolLeft +  boxEl.offsetWidth + 48 > document.body.clientWidth){
            boxEl.style.transform = 'translateX(-90%)';
            icon.style.left = '90%'
        }
     },
    },
    created(){
        
    },
   async mounted(){
        this.allOptions = this.allOptionsObj[this.seachType]
        this.options = this.allOptions 
        document.querySelector('#checkAll').click()
        this.setposition()
    },
    beforeMount(){
        let that = this
        this._close = e=>{
            let isFlag = that.$el.contains(e.target) || e.target.className.indexOf('el-icon-caret-bottom') != -1
            if(!isFlag){
                that.$emit('closeTool')
            }
        }
        document.body.addEventListener('click',this._close)
    },
    beforeDestroy(){
        document.body.removeEventListener('click',this._close)
    },
  };
</script>

<style lang="scss" 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;
    }
    .bottom{
        display: flex;
        justify-content: flex-end;
        margin-top: 10px;
    }
    .el-icon-caret-top{
        position: absolute;
        color: #fff;
        top: -10px;
    }

}

</style>

使用组件

<template>
    <div>
    <el-table :data="tableList" max-height="500" border >
         <el-table-column prop="name" label="姓名">
             <template v-slot:header>
                 <div>
                     <span class="table-heard-filter">姓名</span>
                     <i class="el-icon-caret-bottom" @click="filterData($event,'name')"></i>
                 </div>
             </template>
         </el-table-column>
         <el-table-column prop="address" label="地址" >
              <template v-slot:header>
                 <div>
                     <span class="table-heard-filter">地址</span>
                     <i class="el-icon-caret-bottom" @click="filterData($event,'address')"></i>
                 </div>
             </template>
         </el-table-column>
       <el-table-column prop="date" label="时间">
            <template v-slot:header>
               <div>
                   <span class="table-heard-filter">时间</span>
                   <i class="el-icon-caret-bottom" @click="filterData($event,'date')"></i>
               </div>
           </template>
       </el-table-column>
    </el-table>
    <tableTool v-if="showFilterTool" :seachData="seachData" @saveSeach="saveSeach" :allOptionsObj="allOptionsObj" :seachType="seachType" :filterToolLeft="filterToolLeft" :filterToolTop="filterToolTop" @closeTool="closeTool" />
    </div>
</template>
<script>
import tableTool from './tableTool.vue'
export default {
    name:'test',
    components:{
        tableTool
    },
    data(){
        return{
            seachData:{
                name:[],
                address:[],
                date:[],
            },
            seachType:'',
            allOptionsObj:{
                name:['王小虎','小明','小红','小兰'],
                address:['北京','上海','广州','深圳','长沙'],
                date:['2016','2017','2017','2019'],
            },
            positionTypeList:[],
            tableList:[],
            // 分页数据
            editType:'',
            showFilterTool:false,
            filterToolTop:0,
            filterToolLeft:0,
        }
    },
    methods:{
        filterData(e,type){
            this.showFilterTool = false
            this.$nextTick(()=>{
                this.seachType = type
                this.filterToolTop = e.pageY
                this.filterToolLeft = e.pageX
                this.showFilterTool = true
            })
        },
        closeTool(){
            this.showFilterTool = false
        },
        saveSeach(data){
            console.log(data);
            this.seachData = data
            this.closeTool()
        },
        close(){
           this.showAdd = false 
        },
        saveBatch(data){
            // 查询条件
           console.log(data);
        },
        getList(){
          this.tableList = [{
            date: '2019',
            name: '王小虎',
            address: '上海'
          }, {
            date: '2016',
            name: '小明',
            address: '北京'
          }, {
            date: '2017',
            name: '小红',
            address: '长沙'
          }, {
            date: '2018',
            name: '小兰',
            address: '深圳'
          },{
            date: '2018',
            name: '小兰',
            address: '长沙'
          }]
        }
    },
    created(){
        this.getList()
    }
}
</script>
<style lang="less" scoped>
.table-heard-filter{
    margin-right: 10px !important;
}
.fitlter-btn{
    border: #000 solid 1px;
    padding: 1px;
    background: #1890FF;
    color: #fff;
    border-radius: 5px;
}
</style>

各种数据请使用后台接口获取。

实现效果

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

elementUI + vue实现 Excel筛选功能 的相关文章

  • 如何使用javascript确保元素仅在圆上朝一个方向移动?

    好吧 我承认我对三角学真的很糟糕 出于上下文的考虑 我将添加我在这里提到的问题中的内容 参考问题 https stackoverflow com a 39429290 168492 https stackoverflow com a 394
  • 如何在网站上使用 svg 元素制作块的屏幕截图?

    我在网站上创建了一个构造函数 其本质是将所选元素及其颜色 svg中的元素 添加到访问者选择的背景和背景颜色 png中的背景 中 然后必须单击 保存 结果 按钮并仅执行工作区的屏幕截图 我写了这个脚本 但它需要屏幕截图 但只有背景 并忽略选定
  • 两列表:一列尽可能小,另一列占据其余部分

    我在 div 中有一个 to columns 表 div table tbody tr td class action a a td td class content p Bigger text variable size p td tr
  • 导航栏下拉菜单(折叠)在 Bootstrap 5 中不起作用

    我在尝试使用以下命令创建响应式菜单或下拉按钮时遇到问题Bootstrap 5一切似乎都正常 导航图标和下拉图标出现 但它不起作用 当我单击nav图标或dropdown按钮 无dropdown menu apears 我想特别提到的是 我还包
  • 为什么 setTimeout 在 Chrome 中触发两次,而在 IE 或 Firefox 中则不然?

    有人能告诉我为什么 javascript 函数 生成新号码 在 Chrome 中触发两次 但在 IE 或 Firefox 中则不会 使用 Chrome 20 0 1132 57 IE9 和 Firefox 13
  • 按下回车键时不刷新页面

    我遇到了一些问题 只要表单中有输入 回车键就会触发页面刷新 下面的代码 如果按下回车并且文本区域 input 中没有输入任何文本 则不会刷新页面 但是如果按下回车并且 input中有输入或者光标位于文本区域 我不确定是什么触发了它 因为 s
  • VBA ByRef 参数类型不匹配

    最初在我的主代码部分中 我有一个丑陋的 if 语句 尽管它会运行丑陋 我决定将其设为我要调用的函数 这导致我收到错误 编译错误 ByRef 参数类型不匹配 我的假设是该函数需要正确引用 尽管我一直在阅读文档并且不明白为什么 gt 声明 Sh
  • JavaScript推送函数中的动态变量

    我在 JavaScript 中使用推送功能 var chartData for var i 0 i lt 3 i chartData push date new Date year s mon s date s hr s min s sec
  • onclick 事件中未调用函数

    我想在每个 YouTube 链接的末尾添加一些 HTML 以在 litebox 中打开播放器 到目前为止 这是我的代码 document ready function var valid url new RegExp youtube com
  • 如何在另一个自定义 Hook 中使用返回值的自定义 Hook?

    我正在使用 React native 其中有一个名为的自定义 HookuseUser使用以下方法从 AWS Amplify 获取用户信息Auth getUserInfro方法 然后获取返回对象的一部分并用它设置一个状态变量 我还有另一个名为
  • 具有 100% 高度行和 Internet Explorer 9 的表格

    我有以下示例 div style height 150px background color AAAAFF div
  • LeafleteachLayer函数不会迭代所有Layer

    使用 GeoJSON 数据数组创建一些标记 getJSON GetLocationsServlet function data L geoJSON data onEachFeature onEachFeature addTo mymap G
  • 聆听 Angular 2 中的元素可见性

    我正在为我的网络应用程序使用 Bootstrap 和 Angular 2 v4 我想监听指令中的元素以了解可见性变化 我的元素有一个可以隐藏其子元素的父元素hidden sm up我需要在每次隐藏或显示时触发一个函数 div hidden
  • 使用 Javascript 设置 cookie [重复]

    这个问题在这里已经有答案了 我正在尝试构建我的第一个移动应用程序 它需要连接到我的 mysql 数据库并使用 json 返回数据 这很好 目前我有一个登录系统 一旦确定用户名和密码存在 它就会返回一条成功消息 对于下一步 我想在我的页面上使
  • Google Maps API (v3) 添加/更新标记

    编辑 它现在可以工作 但如果用户不允许或没有基于位置的服务 则不会加载 请参阅 jsfiddle 示例接受的答案评论 我已经浏览了一些教程和问题 但我无法安静地理解正在发生的事情 或者在这种情况下 没有发生 当用户单击链接时 我正在加载地图
  • $resource.query 返回分割字符串(字符数组)而不是字符串

    我正在使用像下面这样的 Angular resource angular module app factory data function resource var Con resource api data update method P
  • 从 PHP 数组生成 HTML 表

    我不明白这一点 我需要解决看似简单的问题 但这超出了我的逻辑 我需要编写一个函数 table columns input cols 它将输出一个表 示例 input array apple orange monkey potato chee
  • 使用 next.js 进行服务器端渲染与传统 SSR

    我非常习惯 SSR 意味着页面得到完全刷新并从服务器接收完整 HTML 的方法 其中根据后端堆栈使用 razor pub other 进行渲染 因此 每次用户单击导航链接时 它只会向服务器发送请求 整个页面将刷新 接收新的 HTML 这就是
  • 有没有办法使用 ko.observableArray 作为地图?

    有没有办法使用ko observableArray http knockoutjs com documentation observableArrays html像地图 字典一样 例如 var arr ko observableArray
  • 仅当显式选择行时才关闭 ui-bootstrap typeahead

    我创建了这个jsBin http jsbin com livuqafe 2 edit来证明我遇到的问题 如果您转到此处 请尝试输入 五 并继续 你的自然反应是输入 五 然后按 Tab 如果你想要 五百 你可以向下箭头一次 但是 在这种情况下

随机推荐

  • 软件技术文档撰写要求

    作者 龚云卿 2006 5 30 1 针对性 文档编制以前应分清读者对象 按不同的类型 不同层次的读者 决定怎样适应他们的需要 对于面向管理人员和用户的文档 不应像开发文档 面向软件开发人员 那样过多地使用软件 的专业术语 难以避免使用的词
  • php数字取整

    ceil 进一法取整 floor 舍去法取整 round 对浮点数进行四舍五入说明 intval 对变数转成整数型态 echo ceil 4 3 5 echo floor 4 3 4 echo round 3 4 3 echo round
  • java.util.Objects.isNull vs object == null 之Objects类的介绍

    Java7引入了java util Objects类 Objects提供了很多工具类方法 其中包括isNull方法 Java8引入了isNull方法 那么java util Objects isNull 与 object null有何区别
  • Android作业中遇到的各种问题

    1 如何设置Edit View不可输入不可编辑不可点击 eidtex为要设置的文本框的id eidtext setEnabled false 去掉点击时编辑框下面横线 eidtext setFocusable false 不可编辑 eidt
  • antd vue时间选择器(年选择器)

    antd vue时间选择器 年选择器 最近项目中用到了antd vue 项目中的版本是1 5 2版本 在做日期选择器时发现只有日 周 月份选择器 独独缺少年份选择器 如果你的项目也是怕升级对整体影响太多 不妨试试下面这种方式来达到年份选择效
  • 用递归求和:1+2+3+4+....n.

    1 具体代码实现 public class Example2 public static void main String args int n 100 int value add n System out println value pu
  • Windows下 VS2015编译RocksDB

    VS2015编译RocksDB RocksDB 是一个来自 facebook 的可嵌入式的支持持久化的 key value 存储系统 也可作为 C S 模式下的存储数据库 但主要目的还是嵌入式 RocksDB 基于 LevelDB 构建 1
  • python在定位元素中加入参数化

    我们在web自动化时 需要用到上个定位的值 来定位下个定位的方法 这个时候就需要用参数传递了 解决如下 我们如果要想获取这个页面的全部名字需要用 driver find elements的定位 不要用driver find element
  • 单片机新手指导2:STM32单片机学习步骤---偏编程方向

    学习步骤 编程方向 写在前面 本文为笔者从单片机小白到略懂到能完成单片机大项目过程中的身心体会 做下总结供后来者参考 第零步 1 准备好一个爱学习 痴迷技术 不怕秃头 不怕熬夜 追求上进的自己 2 调研并选一套适合自己的STM32学习板 不
  • 关于windows安装wsl,出现WslRegisterDistribution failed with error: 0x8007019e The Windows Subsystem错误的解决方案

    前倾概要 在Microsoft store安装ubuntu 18 04成功启动后 出现了该错误并提示按任意键退出 如下图所示 由于我忘了截图 所以只能去别的博主那盗图 解决方案 首先需要安装windows的子系统支持 步骤 1 win x
  • Qlistwidget获取当前选项的文本的方法

    PYQT5 Qlistwidget获取当前选项文本的方法 创建一个Qlistwidget 获取当前的选择的item currentItem self listWidget types currentItem print currentIte
  • 提升学生群体中的STEAM教育核心素养

    STEAM教育源自STEM教育 是当今国际探索21世纪人才培养的一种教育理念与举措 美国首倡STEM教育并将其作为提升国家竞争力的战略之一 旨在加强科学 Science 技术 Technology 工程 Engineering 与数学 Ma
  • 基于MVC架构的项目中的数据库数据表结构的更新

    1 在整个项目中对于数据库的操作及其处理 是通过在model类中添加数据模型i类之后去在controllers中执行增加新的构架和迁移文件的方式 最后通过这个迁移来更新数据库 采用第一种方法的现在知道的好处就是因为表的定义是在程序中弄得再通
  • winserver2008 服务器添加新用户及设置远程桌面管理

    winserver2008 服务器添加新用户及设置远程桌面管理 1 点击 开始 管理工具 计算机管理 本地用户和组 2 右击 用户 执行 新用户 命令 如图 输人用户信息 在 新用户 对话框中 输人相应信息 3 单击 创建 按钮完成创建 而
  • 100个 ChatGPT 提示(Prompt)优化高质量提问案例

    众所周知 如何使用好 ChatGPT 关键在于如何提问 如何提出高质量的问题 这就涉及到如何组织提示 Prompt OpenAI 官方称之为提示工程 Prompt Engineering 我们可以通过在提问环节对提示进行优化来得到最准确和相
  • 删除本地缓存localStorage的某个字段

    移除localStorage 某个对应的字段 localStorage removeItem maxPostion this itemInfo itemid 删除localStorage 里的数组 function f i var list
  • 文明重启如何修改服务器,文明重启如何开启社区服 创建社区服方法

    现在在文明重启中 我们除了可以玩普通的模式之外 还可以自己当服主 创建社区服 邀请其他的玩家跟自己一起玩 那么文明重启如何开启社区服呢 感兴趣的小伙伴跟着小编一起来看看创建的方法吧 文明重启如何开启社区服 社区服的开启方法其实很简单 但是首
  • 焊接技巧视频(热风枪/QFP/QFN/SOP/穿孔/烙铁头/助焊膏/连锡/飞线/回流焊)

    https www bilibili com video BV1wJ411B73v p 1 vd source cc0e43b449de7e8663ca1f89dd5fea7d
  • 【ModelArts系列】华为ModelArts Notebook训练yolov3模型(开发环境)

    一 参考资料 二 相关介绍 在ModelArts的 notebook中运行ModelZoo中模型 以yolov3为例 训练集为 COCO2014 运行环境 ModelArts notebook 模型 ModelZoo yolov3 数据集
  • elementUI + vue实现 Excel筛选功能

    element仿照EXCEL 和后端交互数据联动筛选 公司要el table基础上实现一个excel的功能 element的不能满足我的需求于是自己写了一个 tableTool vue组件实现 组件介绍 组件为筛选框 配合element中e