添加筛选

This commit is contained in:
2023-04-21 14:04:17 +08:00
parent 0e1d469c76
commit d712290847
15 changed files with 2466 additions and 936 deletions

View File

@@ -116,6 +116,8 @@ props.columns.map((value: any) => {
});
const rowClick = function (data: any, evt: MouseEvent) {
let click = new Event("click")
window.dispatchEvent(click)
emit("row", data, evt);
};

View File

@@ -3,7 +3,7 @@
@import "../dropdown/index.less";
@import "../page/index.less";
@import "../empty/index.less";
@import "../../css/soultable.less";
.layui-table-col-special {
width: 34px;
}

View File

@@ -24,6 +24,7 @@ import LayEmpty from "../empty/index.vue";
import TableRow from "./TableRow.vue";
import TablePage from "./TablePage.vue";
import { nextTick } from "vue";
import soultable from "./soultable.vue";
export interface TableProps {
id?: string;
@@ -70,11 +71,11 @@ const props = withDefaults(defineProps<TableProps>(), {
rowStyle: "",
cellStyle: "",
defaultExpandAll: false,
spanMethod: () => {},
spanMethod: () => { },
expandKeys: () => [],
loading: false,
getCheckboxProps: () => {},
getRadioProps: () => {},
getCheckboxProps: () => { },
getRadioProps: () => { },
});
const emit = defineEmits([
@@ -85,12 +86,15 @@ const emit = defineEmits([
"row-contextmenu",
"row-double",
"row",
"update:page"
]);
const slot = useSlots();
const slots = slot.default && slot.default();
const tableRef = ref();
const datalist = ref([...props.dataSource])
console.log(datalist.value,97)
const s = "";
const allChecked = ref(false);
const hasChecked = ref(false);
@@ -264,6 +268,15 @@ watch(
() => props.dataSource,
() => {
tableDataSource.value = [...props.dataSource];
// if(!props.page){
// datalist.value = [...props.dataSource]
// }else{
// change({
// limit: props.page.limit,
// current: pagecurrent || props.page.current
// })
// }
// 为什么修改数据就要把选中清空? 我要清空不会自己清吗?
// tableSelectedKeys.value = [];
// tableSelectedKey.value = s;
@@ -310,9 +323,32 @@ watch(
},
{ deep: true, immediate: true }
);
watch(tableDataSource,()=>{
if(!props.page){
datalist.value = tableDataSource.value
}else{
// props.page.count = tableDataSource.value.length
let tmp ={...props.page}
tmp.total = tableDataSource.value.length
emit("update:page",tmp)
// tableDataSource.value = endlist
change({
limit: props.page.limit,
current: pagecurrent || props.page.current
})
}
})
watch(()=>props.page,()=>{
console.log(props.page,342)
})
let pagecurrent:number;
const change = function (page: any) {
emit("change", page);
// emit("change", page);
pagecurrent = page.current
datalist.value = tableDataSource.value.slice(
page.limit * (page.current - 1),
page.limit * page.current
);
};
const rowClick = function (data: any, evt: MouseEvent) {
@@ -392,10 +428,10 @@ function base64(s: string) {
}
// 列排序
const sortTable = (e: any, key: string, sort: string) => {
const sortTable = (e: any, key: string, sort: string, issoul = false) => {
let currentSort = e.target.parentNode.getAttribute("lay-sort");
if (sort === "desc") {
if (currentSort === sort) {
if (currentSort === sort && !issoul) {
e.target.parentNode.setAttribute("lay-sort", "");
tableDataSource.value = [...props.dataSource];
} else {
@@ -407,7 +443,7 @@ const sortTable = (e: any, key: string, sort: string) => {
});
}
} else {
if (currentSort === sort) {
if (currentSort === sort && !issoul) {
e.target.parentNode.setAttribute("lay-sort", "");
tableDataSource.value = [...props.dataSource];
} else {
@@ -697,6 +733,72 @@ const toolbarStyle = (toolbarName: string) => {
onBeforeUnmount(() => {
window.onresize = null;
});
// 模仿soultable
const soulstatus = ref(false);
const soultop = ref(0);
const soulleft = ref(0);
const selcolumn = ref<any>({})
const soulkey = ref("")
const sxlist:any = ref({})
function showsoul(event: MouseEvent, column: any, key: string) {
console.log(event);
soulleft.value = event.pageX;
soultop.value = event.pageY;
soulstatus.value = true;
selcolumn.value = column;
soulkey.value = key
}
const heddin = () => {
soulkey.value = ""
}
function asc(event: any) {
selcolumn.value.soulclass = "soul-icon-filter-asc"
sortTable(event, selcolumn.value.key, "asc", true)
}
function desc(event: any) {
selcolumn.value.soulclass = "soul-icon-filter-desc"
sortTable(event, selcolumn.value.key, "desc", true)
}
function sx(e:any){
sxlist.value[e.key] = e.list
}
watch(sxlist,()=>{
// tableDataSource
let list:any = [...props.dataSource]
let endlist:any = []
for(let i in sxlist.value){
for(let j in list){
if(list[j] != "" && sxlist.value[i].length != 0){
if(!sxlist.value[i].includes(list[j][i])){
list[j] = ""
}
}
}
}
for(let i of list){
if(i != ""){
endlist.push(i)
}
}
if(!props.page){
datalist.value = endlist
}else{
tableDataSource.value = endlist
change({
limit: props.page.limit,
current: pagecurrent || props.page.current
})
}
console.log("筛选",endlist)
},{
deep: true
})
window.addEventListener("click", heddin)
// 将分页移入到组件内
</script>
<template>
@@ -709,50 +811,27 @@ onBeforeUnmount(() => {
</div>
<div v-if="defaultToolbar" class="layui-table-tool-self">
<!-- 筛选 -->
<lay-dropdown
v-if="showToolbar('filter')"
updateAtScroll
:style="toolbarStyle('filter')"
>
<lay-dropdown v-if="showToolbar('filter')" updateAtScroll :style="toolbarStyle('filter')">
<div class="layui-inline" title="筛选" lay-event>
<i class="layui-icon layui-icon-slider"></i>
</div>
<template #content>
<div class="layui-table-tool-checkbox">
<lay-checkbox
v-for="column in tableHeadColumns[0]"
v-model="tableColumnKeys"
skin="primary"
:disabled="column.children"
:key="column.key"
:value="column.key"
>{{ column.title }}</lay-checkbox
>
<lay-checkbox v-for="column in tableHeadColumns[0]" v-model="tableColumnKeys" skin="primary"
:disabled="column.children" :key="column.key" :value="column.key">{{ column.title }}</lay-checkbox>
</div>
</template>
</lay-dropdown>
<!-- 导出 -->
<div
v-if="showToolbar('export')"
class="layui-inline"
title="导出"
lay-event
:style="toolbarStyle('export')"
@click="exportData()"
>
<div v-if="showToolbar('export')" class="layui-inline" title="导出" lay-event :style="toolbarStyle('export')"
@click="exportData()">
<i class="layui-icon layui-icon-export"></i>
</div>
<!-- 打印 -->
<div
v-if="showToolbar('print')"
:style="toolbarStyle('print')"
class="layui-inline"
title="打印"
lay-event
@click="print()"
>
<div v-if="showToolbar('print')" :style="toolbarStyle('print')" class="layui-inline" title="打印" lay-event
@click="print()">
<i class="layui-icon layui-icon-print"></i>
</div>
</div>
@@ -764,47 +843,26 @@ onBeforeUnmount(() => {
<div class="layui-table-box">
<!-- 表头 -->
<div
class="layui-table-header"
:style="[{ 'padding-right': `${scrollWidthCell}px` }]"
>
<div class="layui-table-header" :style="[{ 'padding-right': `${scrollWidthCell}px` }]">
<div class="layui-table-header-wrapper" ref="tableHeader">
<table
class="layui-table"
:lay-size="size"
:lay-skin="skin"
ref="tableHeaderTable"
>
<table class="layui-table" :lay-size="size" :lay-skin="skin" ref="tableHeaderTable">
<colgroup>
<template v-for="column in tableBodyColumns" :key="column">
<template v-if="tableColumnKeys.includes(column.key)">
<col
:width="column.width"
:style="{
minWidth: column.minWidth ? column.minWidth : '50px',
}"
/>
<col :width="column.width" :style="{
minWidth: column.minWidth ? column.minWidth : '50px',
}" />
</template>
</template>
</colgroup>
<thead>
<template
v-for="(
tableHeadColumn, tableHeadColumnIndex
) in tableHeadColumns"
:key="tableHeadColumnIndex"
>
<template v-for="(
tableHeadColumn, tableHeadColumnIndex
) in tableHeadColumns" :key="tableHeadColumnIndex">
<tr>
<template
v-for="(column, columnIndex) in tableHeadColumn"
:key="column"
>
<th
v-if="tableColumnKeys.includes(column.key)"
:colspan="column.colspan"
:rowspan="column.rowspan"
class="layui-table-cell"
:class="[
<template v-for="(column, columnIndex) in tableHeadColumn" :key="column">
<th v-if="tableColumnKeys.includes(column.key)" :colspan="column.colspan" :rowspan="column.rowspan"
class="layui-table-cell" :class="[
renderFixedClassName(column, columnIndex),
column.fixed
? `layui-table-fixed-${column.fixed}`
@@ -818,8 +876,7 @@ onBeforeUnmount(() => {
column.type == 'number'
? 'layui-table-cell-number'
: '',
]"
:style="[
]" :style="[
{
textAlign: column.align,
},
@@ -828,16 +885,10 @@ onBeforeUnmount(() => {
columnIndex,
tableHeadColumn
),
]"
>
]">
<template v-if="column.type == 'checkbox'">
<lay-checkbox
v-model="hasChecked"
:is-indeterminate="!allChecked"
skin="primary"
value="all"
@change="changeAll"
/>
<lay-checkbox v-model="hasChecked" :is-indeterminate="!allChecked" skin="primary" value="all"
@change="changeAll" />
</template>
<template v-else>
<span>
@@ -849,23 +900,20 @@ onBeforeUnmount(() => {
</template>
</span>
<!-- 插槽 -->
<span
v-if="column.sort"
class="layui-table-sort layui-inline"
lay-sort
>
<i
@click.stop="sortTable($event, column.key, 'asc')"
class="layui-edge layui-table-sort-asc"
title="升序"
></i>
<i
@click.stop="
sortTable($event, column.key, 'desc')
"
class="layui-edge layui-table-sort-desc"
title="降序"
></i>
<span v-if="column.sort" class="layui-table-sort layui-inline" lay-sort>
<i @click.stop="sortTable($event, column.key, 'asc')" class="layui-edge layui-table-sort-asc"
title="升序"></i>
<i @click.stop="
sortTable($event, column.key, 'desc')
" class="layui-edge layui-table-sort-desc" title="降序"></i>
</span>
<span v-if="column.soul" class="layui-table-sort layui-inline soul-icon">
<i class="soul-icon soul-box" :class="column.soulclass || 'soul-icon-filter'"
@click.stop="showsoul($event, column, column.key)">
<!-- <div v-show="column.soulshow" @click.stop="" class="soulbox">
11111
</div> -->
</i>
</span>
</template>
</th>
@@ -877,64 +925,29 @@ onBeforeUnmount(() => {
</div>
</div>
<!-- 表身 -->
<div
class="layui-table-body layui-table-main"
:style="{ height: height, maxHeight: maxHeight }"
ref="tableBody"
>
<table
class="layui-table"
v-if="tableDataSource.length > 0 && loading == false"
:class="{ 'layui-table-even': props.even }"
:lay-size="size"
:lay-skin="skin"
>
<div class="layui-table-body layui-table-main" :style="{ height: height, maxHeight: maxHeight }" ref="tableBody">
<table class="layui-table" v-if="datalist.length > 0 && loading == false"
:class="{ 'layui-table-even': props.even }" :lay-size="size" :lay-skin="skin">
<colgroup>
<template
v-for="(column, columnIndex) in tableBodyColumns"
:key="columnIndex"
>
<template v-for="(column, columnIndex) in tableBodyColumns" :key="columnIndex">
<template v-if="tableColumnKeys.includes(column.key)">
<col
:width="column.width"
:style="{
minWidth: column.minWidth ? column.minWidth : '50px',
}"
/>
<col :width="column.width" :style="{
minWidth: column.minWidth ? column.minWidth : '50px',
}" />
</template>
</template>
</colgroup>
<tbody>
<!-- 渲染 -->
<template
v-for="(children, index) in tableDataSource"
:key="index"
>
<table-row
:id="id"
:index="index"
:data="children"
:columns="tableBodyColumns"
:indent-size="indentSize"
:currentIndentSize="currentIndentSize"
:tableColumnKeys="tableColumnKeys"
:expandSpace="childrenExpandSpace"
:expandIndex="expandIndex"
:cellStyle="cellStyle"
:cellClassName="cellClassName"
:rowStyle="rowStyle"
:rowClassName="rowClassName"
:spanMethod="spanMethod"
:defaultExpandAll="defaultExpandAll"
:getCheckboxProps="getCheckboxProps"
:getRadioProps="getRadioProps"
v-model:expandKeys="tableExpandKeys"
v-model:selectedKeys="tableSelectedKeys"
v-model:selectedKey="tableSelectedKey"
@row="rowClick"
@row-double="rowDoubleClick"
@row-contextmenu="rowContextmenu"
>
<template v-for="(children, index) in datalist" :key="index">
<table-row :id="id" :index="index" :data="children" :columns="tableBodyColumns" :indent-size="indentSize"
:currentIndentSize="currentIndentSize" :tableColumnKeys="tableColumnKeys"
:expandSpace="childrenExpandSpace" :expandIndex="expandIndex" :cellStyle="cellStyle"
:cellClassName="cellClassName" :rowStyle="rowStyle" :rowClassName="rowClassName"
:spanMethod="spanMethod" :defaultExpandAll="defaultExpandAll" :getCheckboxProps="getCheckboxProps"
:getRadioProps="getRadioProps" v-model:expandKeys="tableExpandKeys"
v-model:selectedKeys="tableSelectedKeys" v-model:selectedKey="tableSelectedKey" @row="rowClick"
@row-double="rowDoubleClick" @row-contextmenu="rowContextmenu">
<template v-for="name in slotsData" #[name]="{ data }">
<slot :name="name" :data="data"></slot>
</template>
@@ -944,42 +957,33 @@ onBeforeUnmount(() => {
</table-row>
</template>
<tr v-if="hasTotalRow" class="layui-table-total">
<template
v-for="(column, columnIndex) in columns"
:key="columnIndex"
>
<template v-for="(column, columnIndex) in columns" :key="columnIndex">
<template v-if="tableColumnKeys.includes(column.key)">
<td
:style="[
{
textAlign: column.align,
whiteSpace: column.ellipsisTooltip
? 'nowrap'
: 'normal',
},
renderFixedStyle(column, columnIndex),
]"
:class="[
'layui-table-cell',
renderFixedClassName(column, columnIndex),
column.fixed ? `layui-table-fixed-${column.fixed}` : '',
]"
v-html="renderTotalRowCell(column)"
></td>
<td :style="[
{
textAlign: column.align,
whiteSpace: column.ellipsisTooltip
? 'nowrap'
: 'normal',
},
renderFixedStyle(column, columnIndex),
]" :class="[
'layui-table-cell',
renderFixedClassName(column, columnIndex),
column.fixed ? `layui-table-fixed-${column.fixed}` : '',
]" v-html="renderTotalRowCell(column)"></td>
</template>
</template>
</tr>
</tbody>
</table>
<template v-if="tableDataSource.length == 0 && loading == false">
<template v-if="datalist.length == 0 && loading == false">
<lay-empty></lay-empty>
<div :style="{ width: tableBodyEmptyWidth }"></div>
</template>
<template v-if="loading == true">
<div class="layui-table-loading">
<i
class="layui-icon-loading layui-icon layui-anim layui-anim-rotate layui-anim-loop"
></i>
<i class="layui-icon-loading layui-icon layui-anim layui-anim-rotate layui-anim-loop"></i>
</div>
</template>
</div>
@@ -988,23 +992,22 @@ onBeforeUnmount(() => {
</div>
</div>
<div v-if="page && page.total > 0" class="layui-table-page">
<table-page
:total="page.total"
:pages="page.pages"
:theme="page.theme"
:limits="page.limits"
:showSkip="page.showSkip"
:show-page="page.showPage"
:showRefresh="page.showRefresh"
:showLimit="page.showLimit"
:showCount="page.showCount"
:count="page.count"
v-model:current="page.current"
v-model:limit="page.limit"
@change="change"
>
<table-page :total="page.total" :pages="page.pages" :theme="page.theme" :limits="page.limits"
:showSkip="page.showSkip" :show-page="page.showPage" :showRefresh="page.showRefresh" :showLimit="page.showLimit"
:showCount="page.showCount" :count="page.count" v-model:current="page.current" v-model:limit="page.limit"
@change="change">
</table-page>
</div>
</div>
<div v-for="(
tableHeadColumn, tableHeadColumnIndex
) in tableHeadColumns" :key="tableHeadColumnIndex">
<div v-for="(column, columnIndex) in tableHeadColumn" :key="column">
<soultable :top="soultop" :left="soulleft" v-show="soulkey == column.key" @asc="asc" @desc="desc" :list="props.dataSource"
:soulkey="column.key" @sx="sx"></soultable>
</div>
</div>
</div>
</template>

View File

@@ -0,0 +1,14 @@
.soulbox{
position: absolute;
background-color: #333333;
color: #fff;
display: inline-block;
position: absolute;
z-index: 2147483647;
min-width: 160px;
max-width: 300px;
overflow-y: auto;
border: 1px solid #e6e6e6;
border-radius: 5px;
box-shadow: 2px 2px 4px -2px rgba(0,0,0,.2);
}

View File

@@ -0,0 +1,120 @@
<template>
<div class="soulbox" :style="`top: ${props.top}px;left:${props.left}px`" @click.stop="">
<ul>
<li @click="asc" class="soul-sort" data-value="asc" style=""><i class="soul-icon soul-icon-asc"></i> 升序排列 </li>
<li @click="desc" class="soul-sort" data-value="desc" style="border-bottom: 1px solid rgb(230, 230, 230);"><i
class="soul-icon soul-icon-desc"></i> 降序排列 </li>
<!-- <li class="soul-column" style=""><i class="layui-icon layui-icon-table"></i> 表格列 <i
class="layui-icon layui-icon-right" style="float: right"></i></li> -->
<li class="soul-dropList" style="" @mouseover="selshow = true"><i class="soul-icon soul-icon-drop-list"></i> 筛选数据 <i
class="layui-icon layui-icon-right" style="float: right"></i></li>
<!-- <li class="soul-condition" style=""><i class="soul-icon soul-icon-query"></i> 筛选条件 <i
class="layui-icon layui-icon-right" style="float: right"></i></li>
<li class="soul-edit-condition" style=""><i class="layui-icon layui-icon-edit"></i> 编辑筛选条件 </li>
<li class="soul-export" style=""><i class="soul-icon soul-icon-download"></i> 导出excel </li> -->
</ul>
<div class="soulbox" style="left: 100%;top:65px" v-show="selshow">
<lay-input prefix-icon="layui-icon-search" v-model="seltext" size="sm" placeholder="关键字搜索">
</lay-input>
<div class="check" style="min-width: 180px;">
<div class="multiOption" data-type="all" @click="select(1)"><i class="soul-icon"></i> 全选</div>
<div class="multiOption" data-type="none" @click="select(2)"><i class="soul-icon"></i> 清空</div>
<div class="multiOption" data-type="reverse" @click="select(3)"><i class="soul-icon"></i>反选</div>
</div>
<ul>
<LayCheckboxGroup v-model="sel">
<li v-for="i, j in list">
<LayCheckbox skin="primary" :value="i"></LayCheckbox>{{ i }}
</li>
</LayCheckboxGroup>
</ul>
</div>
</div>
</template>
<script lang="ts" setup>
import "./soultable.less"
import { ref, watch, withDefaults } from "vue";
import layInput from "../input/index.vue"
import LayCheckbox from "../checkbox/index.vue";
import LayCheckboxGroup from "../checkboxGroup/index.vue";
export interface SoulTableProps {
left: number,
top: number,
list: any,
soulkey: string,
}
const props = withDefaults(defineProps<SoulTableProps>(), {
top: 10,
left: 10,
list: [],
soulkey: ""
})
const emit = defineEmits(["asc", "desc","sx"])
function asc(event: any) {
emit("asc", event)
}
function desc(event: any) {
emit("desc", event)
}
const sel:any = ref([])
const list: any = ref([])
const alllist:any = ref([])
watch(() => [props.list,props.soulkey], () => {
let set = new Set()
for (let i of props.list) {
set.add(i[props.soulkey])
console.log(i, i[props.soulkey])
}
alllist.value = Array.from(set)
list.value = alllist.value
console.log(list.value)
},
{ deep: true })
// watch(alllist,()=>{
// list.value = []
// for(let i of list){
// }
// })
const seltext = ref("")
watch(seltext,()=>{
let l = []
if(seltext.value){
for(let i of alllist.value){
if(i.indexOf(seltext.value) != -1){
l.push(i)
}
}
}else{
l = alllist.value
}
list.value = l
})
watch(sel,()=>{
emit("sx",{key:props.soulkey,list:sel.value})
})
function select(type: number){
if(type == 1){
sel.value = []
let t = []
for(let i of list.value){
t.push(i)
}
sel.value = t
}else if(type == 3){
let t = []
for(let i of list.value){
if(!sel.value.includes(i)){
t.push(i)
}
}
sel.value = t
}else if(type == 2){
sel.value = []
}
}
const selshow = ref(false)
</script>