美文网首页vue让前端飞一起来看vue3
【Vue3+Vite+TS】2.0 组件一:伸缩菜单

【Vue3+Vite+TS】2.0 组件一:伸缩菜单

作者: bobokaka | 来源:发表于2021-12-20 01:38 被阅读0次

    必备UI组件

    伸缩菜单将用到以下几个组件:
    Container 布局容器
    Menu 菜单

    组件设计

    修改路由:
    src\router\index.ts

    import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
    
    import Home from '../views/Home/index.vue'
    import Container from '../components/baseline/container/src/index.vue'
    
    const routes: RouteRecordRaw[] = [
        {
            path: '/',
            component: Container,
            children: [
                {
                    path: '/',
                    component: Home,
                },
            ],
        },
    ]
    
    const router = createRouter({
        routes,
        history: createWebHistory(),
    })
    export default router
    
    

    新建src\components\baseline\container\src\index.vue

    <template>
        <el-container>
            <el-aside width="200px">
                <el-menu default-active="2" class="el-menu-vertical-demo">
                    <el-menu-item index="1">
                        <el-icon><el-icon-menu /></el-icon>
                        <span>导航一</span>
                    </el-menu-item>
                    <el-menu-item index="2">
                        <el-icon><el-icon-menu /></el-icon>
                        <span>导航二</span>
                    </el-menu-item>
                    <el-menu-item index="3">
                        <el-icon><el-icon-menu /></el-icon>
                        <span>导航三</span>
                    </el-menu-item>
                </el-menu>
            </el-aside>
            <el-container>
                <el-header>Header</el-header>
                <el-main>
                    <router-view></router-view>
                </el-main>
            </el-container>
        </el-container>
    </template>
    <script lang="ts" setup></script>
    <style lang="scss" scoped></style>
    

    修改src\App.vue

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

    效果如下:


    image.png

    利用el-menu的collapse属性,可以达到伸缩的效果。

    <template>
        <el-container>
            <el-aside width="200px">
                <el-menu
                    default-active="2"
                    :collapse="isCollapse"
                    class="el-menu-vertical-demo"
                >
                    <el-menu-item index="1">
                        <el-icon><el-icon-menu /></el-icon>
                        <span>导航一</span>
                    </el-menu-item>
                    <el-menu-item index="2">
                        <el-icon><el-icon-menu /></el-icon>
                        <span>导航二</span>
                    </el-menu-item>
                    <el-menu-item index="3">
                        <el-icon><el-icon-menu /></el-icon>
                        <span>导航三</span>
                    </el-menu-item>
                </el-menu>
            </el-aside>
            <el-container>
                <!-- 头部 -->
                <el-header>
                    <span @click="toggle">
                        <el-icon-expand
                            style="margin-right: 10px"
                            v-if="isCollapse"
                        />
                        <el-icon-fold style="margin-right: 10px" v-else />
                    </span>
                </el-header>
                <el-main>
                    <router-view></router-view>
                </el-main>
            </el-container>
        </el-container>
    </template>
    <script lang="ts" setup>
    import { ref } from 'vue'
    const isCollapse = ref(false) //false:默认展开
    
    let toggle = () => {
        isCollapse.value = !isCollapse.value
    }
    </script>
    <style lang="scss" scoped></style>
    
    
    image.png

    发现按钮没有并过来。参考官网的举例,优化:

    <template>
        <el-container>
            <el-aside width="auto">
                <el-menu
                    default-active="2"
                    :collapse="isCollapse"
                    class="el-menu-vertical-demo"
                >
                    <el-menu-item index="1">
                        <el-icon><el-icon-menu /></el-icon>
                        <span>导航一</span>
                    </el-menu-item>
                    <el-menu-item index="2">
                        <el-icon><el-icon-menu /></el-icon>
                        <span>导航二</span>
                    </el-menu-item>
                    <el-menu-item index="3">
                        <el-icon><el-icon-menu /></el-icon>
                        <span>导航三</span>
                    </el-menu-item>
                </el-menu>
            </el-aside>
            <el-container>
                <!-- 头部 -->
                <el-header>
                    <span @click="toggle">
                        <el-icon-expand
                            style="margin-right: 10px"
                            v-if="isCollapse"
                        />
                        <el-icon-fold style="margin-right: 10px" v-else />
                    </span>
                </el-header>
                <el-main>
                    <router-view></router-view>
                </el-main>
            </el-container>
        </el-container>
    </template>
    <script lang="ts" setup>
    import { ref } from 'vue'
    const isCollapse = ref(false) //false:默认展开
    
    let toggle = () => {
        isCollapse.value = !isCollapse.value
    }
    </script>
    <style lang="scss" scoped>
    .el-menu-vertical-demo:not(.el-menu--collapse) {
        width: 200px;
        min-height: 400px;
    }
    </style>
    
    
    image.png

    优化全局样式

    新建src\style\base.scss

    * {
        margin: 0;
        padding: 0;
    }
    svg {
        width: 1em;
        height: 1em;
    }
    html,
    body,
    #app,
    .el-container,
    .el-menu {
        height: 100%;
    }
    
    html {
        font-size: 100px;
    }
    body {
        font-size: 0.12rem;
    }
    
    

    新建src\style\index.scss

    @import './base.scss';
    

    修改src\main.ts

    import { createApp } from 'vue'
    import App from './App.vue'
    import router from './router/index'
    
    import ElementPlus from 'element-plus'
    import 'element-plus/dist/index.css'
    import * as Icons from '@element-plus/icons-vue'
    import { toLine } from './utils'
    
    import './style/index.scss'
    
    const app = createApp(App)
    
    //全局组件注册,牺牲一些性能,但方便使用
    //封装成el-icon-xxx
    for (let i in Icons) {
        // console.log(`i:`, i)
        // console.log('Icons[i]', (Icons as any)[i])
        app.component(`el-icon-${toLine(i)}`, (Icons as any)[i])
    }
    
    app.use(router)
    app.use(ElementPlus)
    app.mount('#app')
    
    

    修改src\App.vue

    <template>
        <router-view></router-view>
    </template>
    <style lang="scss"></style>
    

    这样,可以100px=1rem,修改src\components\baseline\container\src\index.vue,可以调整为:

    <template>
        <el-container>
            <el-aside width="auto">
                <el-menu
                    default-active="1"
                    :collapse="isCollapse"
                    class="el-menu-vertical-demo"
                >
                    <el-menu-item index="1">
                        <el-icon><el-icon-menu /></el-icon>
                        <span>导航一</span>
                    </el-menu-item>
                    <el-menu-item index="2">
                        <el-icon><el-icon-menu /></el-icon>
                        <span>导航二</span>
                    </el-menu-item>
                    <el-menu-item index="3">
                        <el-icon><el-icon-menu /></el-icon>
                        <span>导航三</span>
                    </el-menu-item>
                </el-menu>
            </el-aside>
            <el-container>
                <!-- 头部 -->
                <el-header>
                    <span @click="toggle">
                        <el-icon-expand
                            style="margin-right: 0.1rem"
                            v-if="isCollapse"
                        />
                        <el-icon-fold style="margin-right: 0.1rem" v-else />
                    </span>
                </el-header>
                <el-main>
                    <router-view></router-view>
                </el-main>
            </el-container>
        </el-container>
    </template>
    <script lang="ts" setup>
    import { ref } from 'vue'
    const isCollapse = ref(false) //false:默认展开
    
    let toggle = () => {
        isCollapse.value = !isCollapse.value
    }
    </script>
    <style lang="scss" scoped>
    .el-menu-vertical-demo:not(.el-menu--collapse) {
        width: 2rem;
        min-height: 4rem;
    }
    </style>
    

    组件抽离

    修改src\components\baseline\container\src\index.vue

    <template>
        <el-container>
            <el-aside width="auto">
                <nav-aside :collapse="isCollapse" />
            </el-aside>
            <el-container>
                <!-- 头部 -->
                <el-header>
                    <nav-header v-model:collapse="isCollapse" />
                </el-header>
                <el-main>
                    <router-view></router-view>
                </el-main>
            </el-container>
        </el-container>
    </template>
    <script lang="ts" setup>
    import { ref } from 'vue'
    import NavAside from './navAside/index.vue'
    import NavHeader from './navHeader/index.vue'
    const isCollapse = ref(false) //false:默认展开
    </script>
    <style lang="scss" scoped></style>
    
    

    新建src\components\baseline\container\src\navHeader\index.vue

    <template>
        <span @click="toggle">
            <el-icon-expand style="margin-right: 0.1rem" v-if="collapse" />
            <el-icon-fold style="margin-right: 0.1rem" v-else />
        </span>
    </template>
    
    <script lang="ts" setup>
    /**
     * 头部图标
     **/
    let props = defineProps<{ collapse: boolean }>()
    let emits = defineEmits(['update:collapse'])
    //需要修改父组件的数据
    let toggle = () => {
        emits('update:collapse', !props.collapse)
    }
    </script>
    <style lang="scss" scoped></style>
    
    

    新建src\components\baseline\container\src\navAside\index.vue

    <template>
        <el-menu
            default-active="1"
            :collapse="collapse"
            class="el-menu-vertical-demo"
        >
            <el-menu-item index="1">
                <el-icon><el-icon-menu /></el-icon>
                <span>首页</span>
            </el-menu-item>
            <el-menu-item index="2">
                <el-icon><el-icon-menu /></el-icon>
                <span>图标选择器</span>
            </el-menu-item>
            <el-menu-item index="3">
                <el-icon><el-icon-menu /></el-icon>
                <span>趋势标记</span>
            </el-menu-item>
        </el-menu>
    </template>
    <script lang="ts" setup>
    let props=defineProps<{collapse:boolean}>()
    </script>
    <style lang="scss" scoped>
    .el-menu-vertical-demo:not(.el-menu--collapse) {
        width: 2rem;
        min-height: 4rem;
    }
    </style>
    
    
    image.png

    样式优化

    修改src\components\baseline\container\src\index.vue

    <template>
        <el-container>
            <el-aside width="auto">
                <nav-aside :collapse="isCollapse" />
            </el-aside>
            <el-container>
                <!-- 头部 -->
                <el-header>
                    <nav-header v-model:collapse="isCollapse" />
                </el-header>
                <el-main>
                    <router-view></router-view>
                </el-main>
            </el-container>
        </el-container>
    </template>
    <script lang="ts" setup>
    import { ref } from 'vue'
    import NavAside from './navAside/index.vue'
    import NavHeader from './navHeader/index.vue'
    const isCollapse = ref(false) //false:默认展开
    </script>
    <style lang="scss" scoped>
    .el-header {
        padding: 0;
        border-bottom: 2px solid #eee;
    }
    </style>
    

    修改src\components\baseline\container\src\navHeader\index.vue

    <template>
        <div class="bs-wrapper">
            <span @click="toggle">
                <el-icon-expand style="margin-right: 0.1rem" v-if="collapse" />
                <el-icon-fold style="margin-right: 0.1rem" v-else />
            </span>
        </div>
    </template>
    
    <script lang="ts" setup>
    /**
     * 头部图标
     **/
    let props = defineProps<{ collapse: boolean }>()
    let emits = defineEmits(['update:collapse'])
    //需要修改父组件的数据
    let toggle = () => {
        emits('update:collapse', !props.collapse)
    }
    </script>
    <style lang="scss" scoped>
    .bs-wrapper {
        height: 0.6rem;
        padding: 0 0.2rem;
        display: flex;
        align-items: center;
    }
    </style>
    
    
    image.png

    相关文章

      网友评论

        本文标题:【Vue3+Vite+TS】2.0 组件一:伸缩菜单

        本文链接:https://www.haomeiwen.com/subject/sxyafrtx.html