feat(components): 新增创建分类和笔记对话框及头部组件
- 新增 CreateGroupDialog 组件用于创建分类 - 新增 CreateNoteDialog 组件用于创建笔记 - 新增 HomeHeader 组件用于显示主页头部信息 - 对话框组件使用 Element Plus 样式- 头部组件包含用户操作按钮和搜索功能
This commit is contained in:
172
biji-qianduan/src/components/home/HomeHeader.vue
Normal file
172
biji-qianduan/src/components/home/HomeHeader.vue
Normal file
@@ -0,0 +1,172 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- Desktop Header -->
|
||||
<el-header class="header" v-if="!isMobile">
|
||||
<h1 @click="$emit('reset-view')" style="cursor: pointer; flex-grow: 1;">我的笔记</h1>
|
||||
<div class="actions">
|
||||
<el-input
|
||||
:model-value="searchKeyword"
|
||||
@update:model-value="$emit('update:searchKeyword', $event)"
|
||||
placeholder="搜索笔记标题"
|
||||
class="search-input"
|
||||
@keyup.enter="$emit('search')"
|
||||
>
|
||||
<template #append>
|
||||
<el-button @click="$emit('search')">
|
||||
<el-icon><Search /></el-icon>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
<div v-if="userStore.isLoggedIn" class="user-actions">
|
||||
<span class="welcome-text">欢迎, {{ userStore.userInfo?.username }}</span>
|
||||
<el-button type="danger" @click="$emit('logout')">退出</el-button>
|
||||
<el-button type="primary" @click="$emit('show-update-password')">修改密码</el-button>
|
||||
<el-button type="warning" @click="$emit('show-system-settings')">系统管理</el-button>
|
||||
<el-button type="primary" @click="$emit('show-create-note')">新建笔记</el-button>
|
||||
<el-upload
|
||||
class="upload-btn"
|
||||
action=""
|
||||
:show-file-list="false"
|
||||
:before-upload="handleUpload"
|
||||
accept=".md"
|
||||
>
|
||||
<el-button type="success">上传Markdown</el-button>
|
||||
</el-upload>
|
||||
</div>
|
||||
<div v-else class="guest-actions">
|
||||
<el-button type="primary" @click="goToLogin">登录</el-button>
|
||||
<el-button @click="goToRegister">注册</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-header>
|
||||
|
||||
<!-- Mobile Header -->
|
||||
<el-header class="header mobile-header" v-if="isMobile">
|
||||
<el-button @click="$emit('toggle-collapse')" text circle class="mobile-menu-toggle">
|
||||
<el-icon size="24"><Menu /></el-icon>
|
||||
</el-button>
|
||||
<h1 class="mobile-title" @click="$emit('reset-view')">我的笔记</h1>
|
||||
<el-button text circle class="mobile-search-toggle" @click="$emit('search')">
|
||||
<el-icon size="22"><Search /></el-icon>
|
||||
</el-button>
|
||||
<el-button v-if="!userStore.isLoggedIn" text circle class="mobile-login-toggle" @click="goToLogin">
|
||||
<el-icon size="24"><User /></el-icon>
|
||||
</el-button>
|
||||
</el-header>
|
||||
|
||||
<!-- Mobile Search Bar -->
|
||||
<div v-if="isMobile" class="mobile-search-container">
|
||||
<el-input
|
||||
:model-value="searchKeyword"
|
||||
@update:model-value="$emit('update:searchKeyword', $event)"
|
||||
placeholder="搜索笔记标题"
|
||||
class="mobile-search-input"
|
||||
@keyup.enter="$emit('search')"
|
||||
size="large"
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon><Search /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { Search, Menu, User } from '@element-plus/icons-vue';
|
||||
import { useUserStore } from '@/stores/user';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
const props = defineProps({
|
||||
isMobile: Boolean,
|
||||
searchKeyword: String,
|
||||
});
|
||||
|
||||
const emit = defineEmits([
|
||||
'update:searchKeyword',
|
||||
'search',
|
||||
'reset-view',
|
||||
'logout',
|
||||
'show-update-password',
|
||||
'show-system-settings',
|
||||
'show-create-note',
|
||||
'upload-markdown',
|
||||
'toggle-collapse'
|
||||
]);
|
||||
|
||||
const userStore = useUserStore();
|
||||
const router = useRouter();
|
||||
|
||||
const goToLogin = () => router.push('/login');
|
||||
const goToRegister = () => router.push('/register');
|
||||
|
||||
const handleUpload = (file) => {
|
||||
emit('upload-markdown', file);
|
||||
return false; // Prevent el-upload's default behavior
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 1.5rem;
|
||||
padding: 1rem;
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
backdrop-filter: blur(10px);
|
||||
border-radius: var(--border-radius);
|
||||
box-shadow: var(--box-shadow-light);
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.dark-theme .header {
|
||||
background-color: rgba(30, 30, 47, 0.8);
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
:deep(.search-input .el-input__wrapper) {
|
||||
border-radius: var(--border-radius) !important;
|
||||
}
|
||||
|
||||
.user-actions, .guest-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.welcome-text {
|
||||
white-space: nowrap;
|
||||
color: var(--text-color-secondary);
|
||||
}
|
||||
|
||||
.upload-btn {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.mobile-header {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
.mobile-title {
|
||||
cursor: pointer;
|
||||
flex-grow: 1;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.mobile-search-container {
|
||||
padding: 0 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
:deep(.mobile-search-input .el-input__wrapper) {
|
||||
border-radius: 9999px !important;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user