163 lines
5.1 KiB
Vue
163 lines
5.1 KiB
Vue
<template>
|
|
<div
|
|
class="card card-dash shadow-xl h-screen"
|
|
:class="[sidebar.isClose ? 'w-31' : 'w-80']"
|
|
>
|
|
<div
|
|
class="card-body flex relative transition-all duration-500 ease-in-out"
|
|
>
|
|
<!-- Avatar and Name -->
|
|
<div class="relative" :class="sidebar.isClose ? 'h-50' : 'h-20'">
|
|
<!-- Img -->
|
|
<div
|
|
class="avatar h-10 fixed top-10"
|
|
:class="sidebar.isClose ? 'left-10' : 'left-7'"
|
|
>
|
|
<div class="rounded-full">
|
|
<img src="../assets/user.svg" alt="User" />
|
|
</div>
|
|
</div>
|
|
<!-- Text -->
|
|
<Transition>
|
|
<div v-if="!sidebar.isClose" class="mx-5 grow fixed left-20 top-11">
|
|
<label class="text-2xl">用户名</label>
|
|
</div>
|
|
</Transition>
|
|
</div>
|
|
|
|
<!-- Toggle Button -->
|
|
<button
|
|
class="btn btn-square rounded-lg p-2 m-3 fixed"
|
|
:class="sidebar.isClose ? 'left-7 top-23' : 'left-60 top-7'"
|
|
@click="sidebar.toggleSidebar"
|
|
>
|
|
<svg
|
|
t="1741694970690"
|
|
:class="sidebar.isClose ? 'rotate-0' : 'rotate-540'"
|
|
class="icon"
|
|
viewBox="0 0 1024 1024"
|
|
version="1.1"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
p-id="4546"
|
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
width="200"
|
|
height="200"
|
|
>
|
|
<path
|
|
d="M803.758 514.017c-0.001-0.311-0.013-0.622-0.018-0.933-0.162-23.974-9.386-47.811-27.743-65.903-0.084-0.082-0.172-0.157-0.256-0.239-0.154-0.154-0.296-0.315-0.451-0.468L417.861 94.096c-37.685-37.153-99.034-37.476-136.331-0.718-37.297 36.758-36.979 97.231 0.707 134.384l290.361 286.257-290.362 286.257c-37.685 37.153-38.004 97.625-0.707 134.383 37.297 36.758 98.646 36.435 136.331-0.718l357.43-352.378c0.155-0.153 0.297-0.314 0.451-0.468 0.084-0.082 0.172-0.157 0.256-0.239 18.354-18.089 27.578-41.922 27.743-65.892 0.004-0.315 0.017-0.631 0.018-0.947z"
|
|
:fill="theme.isLightTheme() ? '#828282' : '#C0C3C8'"
|
|
p-id="4547"
|
|
></path>
|
|
</svg>
|
|
</button>
|
|
|
|
<div class="divider"></div>
|
|
|
|
<ul class="menu h-full w-full">
|
|
<li v-for="item in props.items" class="text-xl my-1">
|
|
<a @click="router.push(item.page)">
|
|
<svg
|
|
t="1741694797806"
|
|
class="icon h-[1.5em] w-[1.5em] opacity-50 mx-1"
|
|
viewBox="0 0 1024 1024"
|
|
version="1.1"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
p-id="2622"
|
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
width="200"
|
|
height="200"
|
|
>
|
|
<path
|
|
d="M192 192m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z"
|
|
p-id="2623"
|
|
></path>
|
|
<path
|
|
d="M192 512m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z"
|
|
p-id="2624"
|
|
></path>
|
|
<path
|
|
d="M192 832m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z"
|
|
p-id="2625"
|
|
></path>
|
|
<path
|
|
d="M864 160H352c-17.7 0-32 14.3-32 32s14.3 32 32 32h512c17.7 0 32-14.3 32-32s-14.3-32-32-32zM864 480H352c-17.7 0-32 14.3-32 32s14.3 32 32 32h512c17.7 0 32-14.3 32-32s-14.3-32-32-32zM864 800H352c-17.7 0-32 14.3-32 32s14.3 32 32 32h512c17.7 0 32-14.3 32-32s-14.3-32-32-32z"
|
|
p-id="2626"
|
|
></path>
|
|
</svg>
|
|
<Transition>
|
|
<p class="break-keep" v-if="!sidebar.isClose">{{ item.text }}</p>
|
|
</Transition>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="divider"></div>
|
|
|
|
<ul class="menu w-full">
|
|
<li>
|
|
<a @click="theme.toggleTheme" class="text-xl">
|
|
<ThemeControlButton />
|
|
<Transition>
|
|
<p v-if="!sidebar.isClose" class="break-keep">改变主题</p>
|
|
</Transition>
|
|
<Transition>
|
|
<ThemeControlToggle v-if="!sidebar.isClose" />
|
|
</Transition>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import iconMenu from "../assets/menu.svg";
|
|
import "../router";
|
|
import { useThemeStore } from "@/stores/theme";
|
|
import { useSidebarStore } from "@/stores/sidebar";
|
|
import ThemeControlButton from "./ThemeControlButton.vue";
|
|
import ThemeControlToggle from "./ThemeControlToggle.vue";
|
|
import router from "../router";
|
|
|
|
const theme = useThemeStore();
|
|
const sidebar = useSidebarStore();
|
|
|
|
type Item = {
|
|
id: number;
|
|
icon: string;
|
|
text: string;
|
|
page: string;
|
|
};
|
|
|
|
interface Props {
|
|
items?: Array<Item>;
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
items: () => [
|
|
{ id: 1, icon: iconMenu, text: "btn1", page: "/" },
|
|
{ id: 2, icon: iconMenu, text: "btn2", page: "/" },
|
|
{ id: 3, icon: iconMenu, text: "btn3", page: "/" },
|
|
{ id: 4, icon: iconMenu, text: "btn4", page: "/" },
|
|
],
|
|
});
|
|
</script>
|
|
|
|
<style scoped lang="postcss">
|
|
@reference "../assets/main.css";
|
|
|
|
* {
|
|
@apply transition-all duration-500 ease-in-out;
|
|
}
|
|
|
|
.v-enter-active,
|
|
.v-leave-active {
|
|
transition: opacity 0.3s ease;
|
|
}
|
|
|
|
.v-enter-from,
|
|
.v-leave-to {
|
|
opacity: 0;
|
|
}
|
|
</style>
|