效果图:
这个布局用到了以下组件:
1.v-navigation-drawer侧边栏
- rail:用来控制侧边栏折叠和展开状态,等于false,是展开状态,否则折叠状态。
- permanent:等于true的时候,无论屏幕大小如何变化,侧边栏始终处于展开状态。
<script setup>
import { ref } from "vue"
import emitter from "@/utils/emitter.js"/*---------------------------导入icon图标------------------*/
import IconDashboard from "~icons/mdi/view-dashboard"
import IconAbout from "~icons/mdi/information"
/*--------------------------------------------------------*///rail=false表示打开状态,侧边栏一开始就是打开状态
const sideBarOpen = ref(false)emitter.on('toggleSideBar', (value) => {sideBarOpen.value = value
})
</script><template><v-navigation-drawerclass="bg-blue-grey-darken-4":rail="sideBarOpen"permanent><v-list><v-list-itemprepend-avatar="https://randomuser.me/api/portraits/women/85.jpg"title="Akbar Smile"subtitle="akbar@qq.com"></v-list-item></v-list><v-divider></v-divider><v-list density="comfortable" nav active-class="bg-blue"><v-list-item title="首页" value="folder" to="/home"><template v-slot:prepend><v-icon><IconDashboard/></v-icon></template></v-list-item><v-list-item title="关于" value="article" to="/about"><template v-slot:prepend><v-icon><IconAbout/></v-icon></template></v-list-item></v-list></v-navigation-drawer>
</template>
2.v-app-bar头部导航
<script setup>
import emitter from "@/utils/emitter.js"
import { ref } from "vue"/*--------------------------导入icon----------------*/
import IconClose from "~icons/mdi/menu-close"
import IconOpen from "~icons/mdi/menu-open"
/*-------------------------------------------------*/const sideBarOpen = ref(false)const toggleSideBar = () => {sideBarOpen.value = !sideBarOpen.valueemitter.emit('toggleSideBar', sideBarOpen.value)
}
</script><template><v-app-bar><template v-slot:prepend><component:is="sideBarOpen ? IconClose : IconOpen"@click="toggleSideBar"class="cursor-pointer text-h6 ml-2"></component></template></v-app-bar>
</template>
3.完整代码
路由:
import { createRouter, createWebHistory} from "vue-router"const Layout = ()=> import('@/views/Layout.vue')
const Home = ()=> import('@/views/Home.vue')
const About=()=>import('@/views/About.vue')const router = createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes: [{path: '/',component: Layout,redirect: 'home',children: [{path: 'home',component: Home},{path: 'about',component: About}]}]
})export default router
App.vue:
<template><router-view></router-view>
</template>
Layout.vue
<script setup>
import SideBar from "@/components/SideBar.vue"
import HeaderBar from "@/components/HeaderBar.vue"
</script><template><v-app><!--侧边栏--><SideBar></SideBar><!--头部导航栏--><HeaderBar></HeaderBar><v-main><router-view></router-view></v-main></v-app>
</template>
SideBar.vue:
<script setup>
import { ref } from "vue"
import emitter from "@/utils/emitter.js"/*---------------------------导入icon图标------------------*/
import IconDashboard from "~icons/mdi/view-dashboard"
import IconAbout from "~icons/mdi/information"
/*--------------------------------------------------------*///rail=false表示打开状态,侧边栏一开始就是打开状态
const sideBarOpen = ref(false)emitter.on('toggleSideBar', (value) => {sideBarOpen.value = value
})
</script><template><v-navigation-drawerclass="bg-blue-grey-darken-4":rail="sideBarOpen"permanent><v-list><v-list-itemprepend-avatar="https://randomuser.me/api/portraits/women/85.jpg"title="Akbar Smile"subtitle="akbar@qq.com"></v-list-item></v-list><v-divider></v-divider><v-list density="comfortable" nav active-class="bg-blue"><v-list-item title="首页" value="folder" to="/home"><template v-slot:prepend><v-icon><IconDashboard/></v-icon></template></v-list-item><v-list-item title="关于" value="article" to="/about"><template v-slot:prepend><v-icon><IconAbout/></v-icon></template></v-list-item></v-list></v-navigation-drawer>
</template>
HeaderBar.vue:
<script setup>
import emitter from "@/utils/emitter.js"
import { ref } from "vue"/*--------------------------导入icon----------------*/
import IconClose from "~icons/mdi/menu-close"
import IconOpen from "~icons/mdi/menu-open"
/*-------------------------------------------------*/const sideBarOpen = ref(false)const toggleSideBar = () => {sideBarOpen.value = !sideBarOpen.valueemitter.emit('toggleSideBar', sideBarOpen.value)
}
</script><template><v-app-bar><template v-slot:prepend><component:is="sideBarOpen ? IconClose : IconOpen"@click="toggleSideBar"class="cursor-pointer text-h6 ml-2"></component></template></v-app-bar>
</template>