|
@@ -1,6 +1,33 @@
|
|
|
<!-- 表头 Excel 风格列过滤:漏斗靠右,支持文本/枚举/数字/时间 -->
|
|
<!-- 表头 Excel 风格列过滤:漏斗靠右,支持文本/枚举/数字/时间 -->
|
|
|
<template>
|
|
<template>
|
|
|
- <el-popover
|
|
|
|
|
|
|
+ <span class="col-header-filter-root">
|
|
|
|
|
+ <span
|
|
|
|
|
+ v-if="showSort"
|
|
|
|
|
+ class="col-header-sort-pair"
|
|
|
|
|
+ @click.stop
|
|
|
|
|
+ >
|
|
|
|
|
+ <button
|
|
|
|
|
+ type="button"
|
|
|
|
|
+ class="col-header-sort-btn"
|
|
|
|
|
+ :class="{ on: sortApi!.isSortActive(prop, 'asc') }"
|
|
|
|
|
+ title="升序"
|
|
|
|
|
+ aria-label="升序"
|
|
|
|
|
+ @click="sortApi!.setSort(prop, 'asc')"
|
|
|
|
|
+ >
|
|
|
|
|
+ ▲
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <button
|
|
|
|
|
+ type="button"
|
|
|
|
|
+ class="col-header-sort-btn"
|
|
|
|
|
+ :class="{ on: sortApi!.isSortActive(prop, 'desc') }"
|
|
|
|
|
+ title="降序"
|
|
|
|
|
+ aria-label="降序"
|
|
|
|
|
+ @click="sortApi!.setSort(prop, 'desc')"
|
|
|
|
|
+ >
|
|
|
|
|
+ ▼
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ <el-popover
|
|
|
:visible="visible"
|
|
:visible="visible"
|
|
|
placement="bottom-end"
|
|
placement="bottom-end"
|
|
|
:width="300"
|
|
:width="300"
|
|
@@ -167,11 +194,12 @@
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
- </el-popover>
|
|
|
|
|
|
|
+ </el-popover>
|
|
|
|
|
+ </span>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
- import { computed, onUnmounted, ref, watch } from 'vue'
|
|
|
|
|
|
|
+ import { computed, inject, onUnmounted, ref, watch } from 'vue'
|
|
|
import { ElMessage } from 'element-plus'
|
|
import { ElMessage } from 'element-plus'
|
|
|
import { Filter, Delete, Close, Check } from '@element-plus/icons-vue'
|
|
import { Filter, Delete, Close, Check } from '@element-plus/icons-vue'
|
|
|
import {
|
|
import {
|
|
@@ -200,6 +228,13 @@
|
|
|
clear: []
|
|
clear: []
|
|
|
}>()
|
|
}>()
|
|
|
|
|
|
|
|
|
|
+ const sortApi = inject<{
|
|
|
|
|
+ setSort: (prop: string, order: 'asc' | 'desc') => void
|
|
|
|
|
+ isSortActive: (prop: string, order?: 'asc' | 'desc') => boolean
|
|
|
|
|
+ } | null>('crmColumnSort', null)
|
|
|
|
|
+
|
|
|
|
|
+ const showSort = computed(() => Boolean(sortApi && props.type === 'datetime'))
|
|
|
|
|
+
|
|
|
const visible = ref(false)
|
|
const visible = ref(false)
|
|
|
const draftText = ref('')
|
|
const draftText = ref('')
|
|
|
const draftKeyword = ref('')
|
|
const draftKeyword = ref('')
|
|
@@ -384,6 +419,13 @@
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
<style scoped lang="scss">
|
|
|
|
|
+ .col-header-filter-root {
|
|
|
|
|
+ display: inline-flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 4px;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
.column-header-filter-btn {
|
|
.column-header-filter-btn {
|
|
|
display: inline-flex;
|
|
display: inline-flex;
|
|
|
flex-shrink: 0;
|
|
flex-shrink: 0;
|