134 lines
3.4 KiB
Vue
134 lines
3.4 KiB
Vue
<template>
|
|
<el-dropdown
|
|
size="medium"
|
|
style="height: 40px;"
|
|
@command="handleCommand"
|
|
>
|
|
<div>
|
|
<el-button round type="text" class="sort">
|
|
<svg-icon
|
|
v-if="currentSortOrder === 'descending'"
|
|
icon-class="sort-amount-down-solid"
|
|
/>
|
|
<svg-icon v-else icon-class="sort-amount-up-alt-solid" />
|
|
<span class="sort-name">{{ currentSortName }}</span>
|
|
</el-button>
|
|
</div>
|
|
<el-dropdown-menu slot="dropdown">
|
|
<el-dropdown-item
|
|
v-for="item in allSortOptions"
|
|
:key="item.key"
|
|
:command="item.command"
|
|
:divided="item.order === 'ascending' && item.key !== 'name-asc'"
|
|
>
|
|
<span :class="{ 'al-file-sort-item': true, active: sortable.prop === item.prop && sortable.order === item.order }">
|
|
<i :class="['al-file-sort-item-icon', (sortable.prop === item.prop && sortable.order === item.order) ? (sortable.order === 'ascending' ? 'el-icon-top' : 'el-icon-bottom') : '']" ></i>
|
|
<span>{{ item.label }}</span>
|
|
</span>
|
|
</el-dropdown-item>
|
|
</el-dropdown-menu>
|
|
</el-dropdown>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'SortDropdown',
|
|
props: {
|
|
// 当前排序状态
|
|
sortable: {
|
|
type: Object,
|
|
required: true,
|
|
validator(value) {
|
|
return value && typeof value.prop === 'string' && typeof value.order === 'string'
|
|
}
|
|
},
|
|
// 排序选项配置
|
|
sortOptions: {
|
|
type: Array,
|
|
default: () => [
|
|
{ command: 'orderName', prop: 'name', title: '名称' },
|
|
{ command: 'orderSize', prop: 'size', title: '大小' },
|
|
{ command: 'orderUploadDate', prop: 'uploadDate', title: '上传时间' },
|
|
{ command: 'orderUpdateDate', prop: 'updateDate', title: '修改时间' }
|
|
]
|
|
}
|
|
},
|
|
computed: {
|
|
// 生成完整的排序选项(包含顺序和倒序)
|
|
allSortOptions() {
|
|
return this.sortOptions.flatMap(option => [
|
|
{
|
|
key: `${option.prop}-asc`,
|
|
command: `${option.command}-ascending`,
|
|
prop: option.prop,
|
|
order: 'ascending',
|
|
title: option.title,
|
|
label: `${option.title} - 顺序`
|
|
},
|
|
{
|
|
key: `${option.prop}-desc`,
|
|
command: `${option.command}-descending`,
|
|
prop: option.prop,
|
|
order: 'descending',
|
|
title: option.title,
|
|
label: `${option.title} - 倒序`
|
|
}
|
|
])
|
|
},
|
|
// 当前排序字段的显示名称
|
|
currentSortName() {
|
|
const currentOption = this.sortOptions.find(option => option.prop === this.sortable.prop)
|
|
return currentOption ? currentOption.title : ''
|
|
},
|
|
// 当前排序方向
|
|
currentSortOrder() {
|
|
return this.sortable.order
|
|
}
|
|
},
|
|
methods: {
|
|
handleCommand(command) {
|
|
const [prop, order] = command.split('-')
|
|
// 向父组件发送排序数据
|
|
this.$emit('sort-change', prop, order)
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.sort {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
}
|
|
|
|
.sort-name {
|
|
margin-left: 4px;
|
|
}
|
|
|
|
.al-file-sort-item {
|
|
display: flex;
|
|
align-items: center;
|
|
width: 100%;
|
|
}
|
|
|
|
.al-file-sort-item.active {
|
|
color: #409eff;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.al-file-sort-item-icon {
|
|
margin-right: 8px;
|
|
width: 14px;
|
|
height: 14px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
/* 确保图标和文字垂直对齐 */
|
|
.al-file-sort-item-icon >>> svg {
|
|
width: 14px;
|
|
height: 14px;
|
|
vertical-align: middle;
|
|
}
|
|
</style>
|