vxe-table icon indicating copy to clipboard operation
vxe-table copied to clipboard

功能需求:添加一个全局渲染筛选方法

Open sweihub opened this issue 1 month ago • 1 comments

这个需求解决了什么问题:

看了最新的API文档,发现到现在为止,一直没有一个可以外部调用全局动态筛选的方法,通过数据源过滤的方法会导致页面全部重新渲染,而且还有性能问题,希望可以增加一个可以全局筛选的方法。

建议的 API 是什么样的:

  1. 开启渲染过滤,条件由用户提供一个匿名函数
vxeTable.setRenderFilter((row) => {
    return row.field.indexOf("xxx") > -1;
});
  1. 重置渲染过滤
vxeTable.setRenderFilte(null);

是否已有其他不错的替代方案:

没有不错的方法,只有很蹩脚的方法

  1. 给一个列设置一个筛选器,用 css 把图标隐藏
  2. 通过设置option.data,然后 vxeTable.updateData()

以下代码实现了一个快速的渲染筛选,用了一个隐藏的过滤器。

<template>
    <div>
        <vxe-input type="search" size="small" placeholder="type to filter" @input="quickSearch" />
        <vxe-table border ref="tableRef" :data="tableData">
            <vxe-column type="seq" width="60"></vxe-column>
            <vxe-column field="name" title="Name" sortable></vxe-column>
            <vxe-column field="role" title="Role" sortable> </vxe-column>
            <vxe-column field="sex" title="Sex" sortable></vxe-column>
            <vxe-column
                field="age"
                title="Age"
                :filters="renderOptions"
                :filter-method="filterRenderAction"
                :filter-recover-method="filterRenderReset"
                header-class-name="dummy"
            >
            </vxe-column>
            <vxe-column field="address" title="Address" sortable></vxe-column>
        </vxe-table>
    </div>
</template>

<script setup>
import { ref } from "vue";
const tableRef = ref();
const tableData = ref([]);
const renderOptions = ref([{ data: "" }]);

function findList() {
    return new Promise((resolve) => {
        setTimeout(() => {
            tableData.value = [
                { id: 10001, name: "Test1", role: "Develop", sex: "Man", age: 28, address: "test abc" },
                { id: 10002, name: "Test2", role: "Test", sex: "Women", age: 22, address: "Guangzhou" },
                { id: 10003, name: "Test3", role: "PM", sex: "Man", age: 32, address: "Shanghai" },
                { id: 10004, name: "Test4", role: "Designer", sex: "Women", age: 36, address: "Guangzhou" },
                { id: 10005, name: "Test5", role: "Develop", sex: "Women", age: 24, address: "Shanghai" },
                { id: 10006, name: "Test6", role: "Designer", sex: "Man", age: 34, address: "test abc" },
                { id: 10007, name: "Test7", role: "PM", sex: "Man", age: 32, address: "Shanghai" },
                { id: 10008, name: "Test8", role: "Designer", sex: "Man", age: 30, address: "Guangzhou" },
                { id: 10009, name: "Test9", role: "Test", sex: "Women", age: 28, address: "test abc" },
                { id: 100010, name: "Test10", role: "Test", sex: "Man", age: 24, address: "Shanghai" },
            ];
            resolve(tableData.value);
        }, 300);
    });
}

function filterRenderAction({ option, row }) {
    const fields = ["name", "role", "sex", "address"];
    let re = new RegExp(option.data, "i");
    for (let i of fields) {
        if (row[i].match(re)) {
            return true;
        }
    }

    return false;
}

function filterRenderReset({ option }) {
    option.data = "";
}

function quickSearch({ value }) {
    const table = tableRef.value;
    if (!table) {
        return;
    }

    const column = table.getColumnByField("age");
    if (value) {
        const option = column.filters[0];
        option.data = value;
        option.checked = true;
        table.updateData();
    } else {
        table.clearFilter(column);
    }
}

findList();
</script>

<style>
/* hide the filter icon */
.dummy .vxe-cell--filter {
    display: none;
}
</style>

sweihub avatar Jun 01 '24 13:06 sweihub