vue结合element-ui表格组件很多功能的前端实现("因为一些原因所以前端实现") 包括搜索 高级查询 条件筛选 排序 分页 导出excel

1,195 阅读2分钟

这个只是用来记录一下,各位看客有更好的建议直接留言,勿喷哈哈。 先贴个成品。

image.png 先是表格先弄出来再弄功能

<el-table :empty-text="(tableData.length==0&&emptyText==true)?'暂无数据':'数据加载中'"
            @sort-change="sortChange"
            :stripe="true" :header-cell-style="{padding:'8px'}"
            :cell-style="{padding:'0 8px'}"
            :row-style="{height:'36px'}" id="out_table"
            :data="tableData.slice((currentPage == 1 || pagesize == '全部') ? 0 : (currentPage - 1) * pagesize, pagesize == '全部' ? tableData.length : ((currentPage * pagesize) >= tableData.length) ? tableData.length : currentPage * pagesize)"
            border style="width: 100%" :show-summary="true" :summary-method="getTotal">
            <el-table-column :sort-orders="['ascending','descending']" :sortable="item.datatype"
                v-for="(item,index) in columns" :align="item.class=='tableLeft'?'left':'right'" :formatter="formatMoney"
                :prop="item.data" :label="item.title" :width="item.width">
            </el-table-column>
        </el-table>
        <el-row>
            <el-col :span="21">
                <div class="font_12">
                    &nbsp;&nbsp;&nbsp;
                    显示第{{(currentPage==1||pagesize=='全部')?1:(currentPage-1)*pagesize}}到第{{pagesize=='全部'?tableData.length:(currentPage*pagesize)>tableData.length?tableData.length:currentPage*pagesize}}条数据
                    共{{tableData.length}}项 (由{{data.length}}条过滤)</div>
            </el-col>
            <el-col :span="3">
                <el-pagination :page-count="count" @current-change="handleCurrentChange" :current-page="currentPage"
                    layout="prev, pager, next"></el-pagination>
            </el-col>
        </el-row>

表格的代码先贴出来了slice跟显示第几到第几我没优化 首先是表格的排序

@sort-change=sortChange

绑定这个事件点击表格的表头的时候就会触发sortChange事件 这个事件接收三个参数第一个column接收的是这个表头配置的对象 第二个参数是排序的规则 第三个就是这个表头的值 我这里是要把整个表格排序所以用的是绑定到表格上的值 中文排序用的是拼音 数字就比大小 事件是比较时间戳

sortChange({ column, order, prop }) {
                this.tableData.sort(compare(column.sortable, prop, order))
            }
            
const compare = function (type, propertyName, sort) {//排序
    return function (obj1, obj2) {
        let value1 = obj1[propertyName]
        let value2 = obj2[propertyName]
        if (type == "string") {
            const res = value1.localeCompare(value2, 'zh')
            return sort === 'ascending' ? res : -res
        } else if (type === 'date') {
            const res = Date.parse(value1) >= Date.parse(value2) ? 1 : -1
            return sort === 'ascending' ? res : -res
        } else if (type === "money") {
            const res = Number(value1) >= Number(value2) ? 1 : -1
            return sort === 'ascending' ? res : -res
        }
    }

}

接下来就是表格的筛选框跟搜索还有高级查询了,高级查询是个弹出框先贴个图 内容是动态的

image.png

这里因为是一个数据多个条件查询所以思路就是使用es6的数组新方法filter来过滤出来符合条件的数据 因为要同时满足select框里面的数据还有高级查询的数据所以分成两个小函数弄了出来不然函数太长了

FunSelect() {//筛选触发的函数
                this.tableData = screen(this.data, this.columns, this.filterList, this.search)
                if (this.tableData.length <= this.currentPage * this.pagesize) {
                    this.currentPage = 1
                }
                this.dialogVisible = false
            },

这里所有的函数都是指向的这一个 为了复用使用的是引入的函数 传入的参数this.data是所有的请求回来的值,this.columns是所有的表头 this.filterList是页面上显示的select框数组 数组里面是一个个对象。对象的值name就是select框前面的汉字 value就是选中的值 key 代表的是举个例子 账户这一行的key代表的就是el-table-column上面prop绑定的item.data 下面贴代码 展示screen函数跟两个筛选用的函数

const screen = function (data, columns, filterList, search) {//筛选框选择完触发的函数
    return data.filter(item => {
        return selectChange(item, filterList, search) && query(item, columns)
    })
}

const selectChange = function (item, filterList, search) {//select框筛选跟search查询
    return filterList.every(key => {
        if (key.quicksearch == 'select') {
            return (item[key.key] == key.value || key.value == '') && (Object.keys(item).some(some => {
                return (item[some] + '').toLowerCase().includes((search + '').toLowerCase())
            }) || search == '')
        } else {
            return (item[key.key] + '').toLowerCase().includes(key.value) && (Object.keys(item).some(some => {
                return (item[some] + '').toLowerCase().includes((search + '').toLowerCase())
            }) || search == '')
        }
    })
}

const query = function (item, columns) {//高级查询
    return columns.every(obj => {
        if (obj.datatype == 'string') {
            if (obj.filter_1 == "") return true
            else return (item[obj.data] + '').toLowerCase().includes((obj.filter_1 + '').toLowerCase())
        } else if (obj.datatype == 'date') {
            if (obj.filter_1 != '' && obj.filter_2 != '') {
                return Date.parse(obj.filter_1) < Date.parse(item[obj.data]) && Date.parse(item[obj.data]) < Date.parse(obj.filter_2)
            } else if (obj.filter_1 != '' && obj.filter_2 == '') {
                return Date.parse(obj.filter_1) < Date.parse(item[obj.data])
            } else if (obj.filter_1 == "" && obj.filter_2 != "") {
                return Date.parse(item[obj.data]) < Date.parse(obj.filter_2)
            } else {
                return true
            }
        } else if (obj.datatype == 'money') {
            if (obj.filter_1 != '' && obj.filter_2 != '') {
                return Number(obj.filter_1) < Number(item[obj.data]) && Number(item[obj.data]) < Number(obj.filter_2)
            } else if (obj.filter_1 != '' && obj.filter_2 == '') {
                return Number(obj.filter_1) < Number(item[obj.data])
            } else if (obj.filter_1 == "" && obj.filter_2 != "") {
                return Number(item[obj.data]) < Number(obj.filter_2)
            } else {
                return true
            }
        }

    })
}

函数有点长但不是很复杂 主要就是判断跟类型转换 filter是符合条件的会过滤出来 every是所有的符合条件才会返回true 主要就这点

接下来是导出excel这个简单

首先是点击的时候传入要导出的表格的名字还有 要把导出的表格id传过去用来获取innetHTML

tableToExcel(name, id) {//导出excel表格
                let str = document.querySelector(`#${id}`).innerHTML
                //Worksheet名
                tableToExcel(str, name)
            }
            
const tableToExcel = function (html, title) {//导出excel
    let worksheet = 'Sheet1'
    let uri = 'data:application/vnd.ms-excel;base64,'; //xls
    //下载的表格模板数据
    let template = `<html xmlns:o="urn:schemas-microsoft-com:office:office" 
    xmlns:x="urn:schemas-microsoft-com:office:excel" 
    xmlns="http://www.w3.org/TR/REC-html40">
    <head><meta charset='UTF-8'><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet>
        <x:Name>${worksheet}</x:Name>
        <x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet>
        </x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]-->
        </head><body><table>${html}</table></body></html>`;
    //下载模板
    const a = document.createElement('a') //创建a标签
    a.style.display = 'none'
    a.href = uri + base64(template) // 指定下载链接
    a.download = title //指定下载文件名
    a.click() //触发下载

    function base64(s) {
        return window.btoa(unescape(encodeURIComponent(s)))
    }
}

还有个排序要下班了明天再说hh