Skip to content

伸缩菜单

布局 没有分出去

(1) app.vue

  • 这里一定注意去掉scoped,不然样式会失效
vue
<template>
    <router-view></router-view>
</template>

<script setup lang="ts"></script>

<style lang="scss">
    html,
    body,
    #app,
    .el-container,
    .el-menu {
        height: 100%;
    }
    svg {
        width: 1em;
        height: 1em;
    }
</style>

(2) 在每个页面或者layout页面

vue
<template>
    <div class="pagecontent">
       页面内容
    </div>
</template>

<script setup lang="ts"></script>

<style lang="scss" scoped>
    .pagecontent {
        height: 100%;
    }
</style>

(3) hooks/menu/useMenu.ts

ts
// 导入vue中的ref函数
import { ref } from 'vue'
// 导出一个名为useMenu的函数
export const useMenu = () => {
    // 定义一个名为isCollapse的ref变量,初始值为false
    let isCollapse = ref(true)
    // 定义一个名为handleOpen的函数,用于处理下拉菜单的点击事件
    const handleOpen = () => {
        console.log('点击了下拉')
    }
    // 定义一个名为handleClose的函数,用于处理收缩菜单的点击事件
    const handleClose = () => {
        console.log('点击了收缩')
    }
    // 返回一个对象,包含isCollapse、handleOpen和handleClose三个属性
    return {
        isCollapse,
        handleOpen,
        handleClose
    }
}

(4) layout.vue

  • 在layout页面中,添加收缩和展开按钮

  • 这里width必须设置auto,类名下面设置具体的宽度

vue

<template>
    <div class="pagecontent">
        <el-container>
            <el-aside width="auto">
                <el-menu
                    default-active="1"
                    :collapse="isCollapse"
                    class="el-menu-vertical-demo"
                    @open="handleOpen"
                    @close="handleClose"
                >
                    <el-menu-item index="1">
                        <el-icon-menu style="width: 18px; height: 18px; margin-right: 5px"></el-icon-menu>
                        <span>导航1</span>
                    </el-menu-item>
                    <el-menu-item index="2">
                        <el-icon-menu style="width: 18px; height: 18px; margin-right: 5px"></el-icon-menu>
                        <span>导航2</span>
                    </el-menu-item>
                    <el-menu-item index="3">
                        <el-icon-menu style="width: 18px; height: 18px; margin-right: 5px"></el-icon-menu>
                        <span>导航3</span>
                    </el-menu-item>
                </el-menu>
            </el-aside>
            <el-container>
                <el-header>
                    <el-icon-expand
                        v-if="isCollapse"
                        @click="isCollapse = false"
                        style="margin-top: 15px; width: 24px; height: 24px; cursor: pointer"
                    ></el-icon-expand>
                    <el-icon-fold
                        v-if="!isCollapse"
                        @click="isCollapse = true"
                        style="margin-top: 15px; width: 24px; height: 24px; cursor: pointer"
                    ></el-icon-fold>
                </el-header>
                <el-main>
                    <router-view></router-view>
                </el-main>
            </el-container>
        </el-container>
    </div>
</template>

<script setup lang="ts">
    import { useMenu } from '@/hooks/menu/useMenu'
    const { isCollapse, handleOpen, handleClose } = useMenu()
</script>

<style scoped lang="scss">
    .pagecontent {
        height: 100%;
        ::v-deep(.el-header) {
            box-shadow: 2px 0 6px rgba(0, 0, 0, 0.35);
        }
    }
    // 没有收缩的时候宽度就是200px
    .el-menu-vertical-demo:not(.el-menu--collapse) {
        width: 200px;
    }
</style>

布局 (单独拿出去)

(1) app.vue

  • 这里一定注意去掉scoped,不然样式会失效
vue
<template>
    <router-view></router-view>
</template>

<script setup lang="ts"></script>

<style lang="scss">
    html,
    body,
    #app,
    .el-container,
    .el-menu {
        height: 100%;
    }
    svg {
        width: 1em;
        height: 1em;
    }
</style>

(2) 在每个页面或者layout页面

vue
<template>
    <div class="pagecontent">
       页面内容
    </div>
</template>

<script setup lang="ts"></script>

<style lang="scss" scoped>
    .pagecontent {
        height: 100%;
    }
</style>

(3) stores/usecollapse.ts

ts
import { ref } from 'vue'
import { defineStore } from 'pinia'

export const useCollapseStore = defineStore('collapse', () => {
    const isCollapse = ref(false)
    const toogle = () => {
        isCollapse.value = !isCollapse.value
    }

    return { isCollapse, toogle }
})

(4) navHeader/index.vue

vue

<template>
    <div>
        <el-icon-expand
            v-if="useCollapseStore().isCollapse"
            @click="toogle"
            style="margin-top: 15px; width: 24px; height: 24px; cursor: pointer"
        ></el-icon-expand>
        <el-icon-fold
            v-if="!useCollapseStore().isCollapse"
            @click="toogle"
            style="margin-top: 15px; width: 24px; height: 24px; cursor: pointer"
        ></el-icon-fold>
    </div>
</template>

<script setup lang="ts">
    import { useCollapseStore } from '@/stores/collapse'
    const { toogle } = useCollapseStore()
</script>

<style lang="scss" scoped></style>

(5) navSide/index.vue

vue
<template>
    <el-menu default-active="1" :collapse="useCollapseStore().isCollapse" class="el-menu-vertical-demo">
        <el-menu-item index="1">
            <el-icon-menu style="width: 18px; height: 18px; margin-right: 5px"></el-icon-menu>
            <span>导航1</span>
        </el-menu-item>
        <el-menu-item index="2">
            <el-icon-menu style="width: 18px; height: 18px; margin-right: 5px"></el-icon-menu>
            <span>导航2</span>
        </el-menu-item>
        <el-menu-item index="3">
            <el-icon-menu style="width: 18px; height: 18px; margin-right: 5px"></el-icon-menu>
            <span>导航3</span>
        </el-menu-item>
    </el-menu>
</template>

<script setup lang="ts">
    import { useCollapseStore } from '@/stores/collapse'
</script>

<style scoped lang="scss">
    // 没有收缩的时候宽度就是200px
    .el-menu-vertical-demo:not(.el-menu--collapse) {
        width: 200px;
    }
</style>

(6) pages/Home/index.vue

vue

<template>
    <div class="pagecontent">
        <el-container>
            <el-aside width="auto">
                <NavSide></NavSide>
            </el-aside>
            <el-container>
                <!--头部开始-->
                <el-header>
                    <NavHeader></NavHeader>
                </el-header>
                <!--头部结束-->
                <!--内容开始-->
                <el-main>
                    <router-view></router-view>
                </el-main>
                <!--内容结束-->
            </el-container>
        </el-container>
    </div>
</template>

<script setup lang="ts">
    import NavSide from './navSide/index.vue'
    import NavHeader from './navHeader/index.vue'
</script>

<style scoped lang="scss">
    .pagecontent {
        height: 100%;
        ::v-deep(.el-header) {
            box-shadow: 2px 0 6px rgba(0, 0, 0, 0.35);
        }
    }
</style>