table-search.vue 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. <template>
  2. <el-input v-model="tableSearch.filter" clearable placeholder="搜索当前表格" @keyup="searchInTable" @clear="searchInTable">
  3. <template #prefix><sc-iconify icon="ep:search"></sc-iconify></template>
  4. </el-input>
  5. </template>
  6. <script setup>
  7. import XEUtils from "xe-utils";
  8. const props = defineProps({
  9. renderOpts: { type: Object, default: () => {} },
  10. params: { type: Object, default: () => {} }
  11. })
  12. const tableSearch = ref({
  13. filter: ""
  14. })
  15. const searchInTable = () => {
  16. const filterName = XEUtils.toValueString(tableSearch.value.filter).trim().toLowerCase();
  17. const tableData = XEUtils.clone(props.params.$grid?.getData(), true);
  18. if (filterName) {
  19. const filterRE = new RegExp(filterName.replace(/([.?*+^$[\]\\(){}|-])/gi, "\\$1"), "gi");
  20. const searchColumns = props.params.$grid?.getColumns()?.filter(col => col.field);
  21. const mapTree = XEUtils.mapTree(tableData, item => {
  22. searchColumns?.forEach(col => XEUtils.set(
  23. item,
  24. col.field,
  25. props.params.$grid?.getCellLabel(item, col.field)
  26. ));
  27. return item;
  28. });
  29. XEUtils.searchTree(mapTree, item => searchColumns?.some(col => XEUtils.toValueString(XEUtils.get(item, col.field)).toLowerCase().includes(filterName)), { isEvery: true });
  30. const data = XEUtils.mapTree(mapTree, row => {
  31. const item = Object.assign({}, row);
  32. searchColumns?.filter(col => col.type === "html").forEach(col => {
  33. XEUtils.set(
  34. item,
  35. col.field,
  36. XEUtils.toValueString(XEUtils.get(item, col.field)).replace(filterRE, match => `<span class="keyword-lighten">${match}</span>`)
  37. )
  38. });
  39. return item;
  40. });
  41. props.params.$grid?.reloadData(data);
  42. props.params.$grid?.setAllTreeExpand(true);
  43. } else props.params.$grid?.reloadData(tableData);
  44. }
  45. </script>
  46. <style scoped>
  47. .el-input {width: 180px;}
  48. </style>