初始化
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import { ArrowDown } from '@element-plus/icons-vue';
|
||||
import {
|
||||
ElButton,
|
||||
ElDropdown,
|
||||
ElDropdownItem,
|
||||
ElDropdownMenu,
|
||||
ElIcon,
|
||||
ElInput,
|
||||
} from 'element-plus';
|
||||
|
||||
import { hasPermission } from '#/api/common/hasPermission.ts';
|
||||
import { $t } from '#/locales';
|
||||
|
||||
// 定义组件属性
|
||||
const props = defineProps({
|
||||
// 按钮配置数组
|
||||
buttons: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
validator: (value) => {
|
||||
return value.every((button) => {
|
||||
return (
|
||||
typeof button.text === 'string' &&
|
||||
(button.key || typeof button.key === 'string')
|
||||
);
|
||||
});
|
||||
},
|
||||
},
|
||||
// 最大显示按钮数量(不包括下拉菜单)
|
||||
maxVisibleButtons: {
|
||||
type: Number,
|
||||
default: 3,
|
||||
},
|
||||
// 搜索框占位符
|
||||
searchPlaceholder: {
|
||||
type: String,
|
||||
default: $t('common.searchPlaceholder'),
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['search', 'button-click', 'buttonClick']);
|
||||
|
||||
// 搜索值
|
||||
const searchValue = ref('');
|
||||
|
||||
// 计算显示的按钮
|
||||
const visibleButtons = computed(() => {
|
||||
return props.buttons.slice(0, props.maxVisibleButtons);
|
||||
});
|
||||
|
||||
// 计算下拉菜单中的按钮
|
||||
const dropdownButtons = computed(() => {
|
||||
const dropdownButtonsTemp = props.buttons.slice(props.maxVisibleButtons);
|
||||
if (dropdownButtonsTemp.length === 0) {
|
||||
return [];
|
||||
}
|
||||
return dropdownButtonsTemp.value.filter((action) => {
|
||||
return hasPermission([action.permission]);
|
||||
});
|
||||
});
|
||||
|
||||
// 处理搜索
|
||||
const handleSearch = () => {
|
||||
emit('search', searchValue.value);
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
searchValue.value = '';
|
||||
emit('search', '');
|
||||
};
|
||||
|
||||
// 处理按钮点击
|
||||
const handleButtonClick = (button) => {
|
||||
emit('buttonClick', {
|
||||
type: 'button',
|
||||
key: button.key,
|
||||
button,
|
||||
data: button.data,
|
||||
});
|
||||
};
|
||||
|
||||
// 处理下拉菜单点击
|
||||
const handleDropdownClick = (button) => {
|
||||
emit('buttonClick', {
|
||||
type: 'dropdown',
|
||||
key: button.key,
|
||||
button,
|
||||
data: button.data,
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="custom-header">
|
||||
<!-- 左侧搜索区域 -->
|
||||
<div class="header-left">
|
||||
<div class="search-container">
|
||||
<div>
|
||||
<ElInput
|
||||
v-model="searchValue"
|
||||
:placeholder="$t('common.searchPlaceholder')"
|
||||
class="search-input"
|
||||
@keyup.enter="handleSearch"
|
||||
clearable
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<ElButton type="primary" auto-insert-space @click="handleSearch">
|
||||
{{ $t('button.query') }}
|
||||
</ElButton>
|
||||
</div>
|
||||
<div>
|
||||
<ElButton auto-insert-space @click="handleReset">
|
||||
{{ $t('button.reset') }}
|
||||
</ElButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧按钮区域 -->
|
||||
<div class="header-right">
|
||||
<!-- 显示的按钮(最多3个) -->
|
||||
<template
|
||||
v-for="(button, index) in visibleButtons"
|
||||
:key="button.key || index"
|
||||
>
|
||||
<ElButton
|
||||
:type="button.type || 'default'"
|
||||
:icon="button.icon"
|
||||
:disabled="button.disabled"
|
||||
v-access:code="button.permission"
|
||||
@click="handleButtonClick(button)"
|
||||
>
|
||||
{{ button.text }}
|
||||
</ElButton>
|
||||
</template>
|
||||
|
||||
<!-- 下拉菜单(隐藏的按钮) -->
|
||||
<ElDropdown
|
||||
v-if="dropdownButtons.length > 0"
|
||||
@command="handleDropdownClick"
|
||||
>
|
||||
<ElButton>
|
||||
{{ $t('button.more')
|
||||
}}<ElIcon class="el-icon--right"><ArrowDown /></ElIcon>
|
||||
</ElButton>
|
||||
<template #dropdown>
|
||||
<ElDropdownMenu>
|
||||
<ElDropdownItem
|
||||
v-for="button in dropdownButtons"
|
||||
:key="button.key"
|
||||
:command="button"
|
||||
:disabled="button.disabled"
|
||||
>
|
||||
<ElIcon v-if="button.icon">
|
||||
<component :is="button.icon" />
|
||||
</ElIcon>
|
||||
<span style="margin-left: 8px">{{ button.text }}</span>
|
||||
</ElDropdownItem>
|
||||
</ElDropdownMenu>
|
||||
</template>
|
||||
</ElDropdown>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.custom-header {
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
.header-left,
|
||||
.header-right {
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.search-container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search-container {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
width: 300px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user