127 lines
2.9 KiB
Vue
127 lines
2.9 KiB
Vue
<template>
|
||
<!-- 桌面/平板:固定侧边栏(不做展开/收起动画) -->
|
||
<aside v-if="!isMobile" class="sidebar-desktop">
|
||
<el-menu router :default-active="activePath" class="sidebar-menu" @select="handleSelect">
|
||
<el-menu-item index="/">
|
||
<el-icon><HomeFilled /></el-icon>
|
||
<span>首页</span>
|
||
</el-menu-item>
|
||
<el-menu-item index="/conversations">
|
||
<el-icon><Message /></el-icon>
|
||
<span>会话记录管理</span>
|
||
</el-menu-item>
|
||
<el-menu-item index="/users">
|
||
<el-icon><User /></el-icon>
|
||
<span>用户管理</span>
|
||
</el-menu-item>
|
||
</el-menu>
|
||
</aside>
|
||
|
||
<!-- 手机端:抽屉菜单(Element Plus 自带隐藏/遮罩/动画) -->
|
||
<el-drawer
|
||
v-else
|
||
v-model="drawerOpen"
|
||
direction="ltr"
|
||
size="250px"
|
||
:with-header="false"
|
||
>
|
||
<el-menu router :default-active="activePath" class="drawer-menu" @select="handleSelect">
|
||
<el-menu-item index="/">
|
||
<el-icon><HomeFilled /></el-icon>
|
||
<span>首页</span>
|
||
</el-menu-item>
|
||
<el-menu-item index="/conversations">
|
||
<el-icon><Message /></el-icon>
|
||
<span>会话记录管理</span>
|
||
</el-menu-item>
|
||
<el-menu-item index="/users">
|
||
<el-icon><User /></el-icon>
|
||
<span>用户管理</span>
|
||
</el-menu-item>
|
||
</el-menu>
|
||
</el-drawer>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||
import { useRoute } from 'vue-router'
|
||
import { HomeFilled, Message, User } from '@element-plus/icons-vue'
|
||
|
||
const props = defineProps({
|
||
modelValue: {
|
||
type: Boolean,
|
||
default: false
|
||
}
|
||
})
|
||
|
||
const emit = defineEmits(['update:modelValue'])
|
||
|
||
const route = useRoute()
|
||
|
||
// 响应式布局:判断是否为手机端
|
||
const isMobile = ref(false)
|
||
|
||
const handleResize = () => {
|
||
isMobile.value = window.innerWidth < 768
|
||
// 切回非手机端时,确保抽屉关闭
|
||
if (!isMobile.value && props.modelValue) {
|
||
emit('update:modelValue', false)
|
||
}
|
||
}
|
||
|
||
onMounted(() => {
|
||
handleResize()
|
||
window.addEventListener('resize', handleResize)
|
||
})
|
||
|
||
onUnmounted(() => {
|
||
window.removeEventListener('resize', handleResize)
|
||
})
|
||
|
||
const activePath = computed(() => route.path)
|
||
|
||
// el-drawer v-model 适配
|
||
const drawerOpen = computed({
|
||
get() {
|
||
return props.modelValue
|
||
},
|
||
set(val) {
|
||
emit('update:modelValue', val)
|
||
}
|
||
})
|
||
|
||
const handleSelect = () => {
|
||
// 手机端点击菜单项后自动关闭抽屉
|
||
if (isMobile.value) {
|
||
emit('update:modelValue', false)
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.sidebar-desktop {
|
||
position: fixed;
|
||
top: 64px;
|
||
left: 0;
|
||
bottom: 0;
|
||
width: 250px;
|
||
background-color: var(--background-color);
|
||
border-right: 1px solid var(--border-color);
|
||
z-index: 99;
|
||
overflow-y: auto;
|
||
|
||
@media (max-width: 1023px) {
|
||
width: 200px;
|
||
}
|
||
}
|
||
|
||
.sidebar-menu,
|
||
.drawer-menu {
|
||
border-right: none;
|
||
}
|
||
|
||
:deep(.el-drawer__body) {
|
||
padding: 0;
|
||
}
|
||
</style>
|