VUE3后台管理系统第三章头部导航栏开发

功能描述头部内容添加导航栏,很常用的功能
在这里插入图片描述
在这里插入图片描述
功能逻辑实现,设置父元素超出自动换行。获取所有菜单项。获取第一个菜单项相对于其父元素的垂直偏移量offsetTop。循环菜单项和第一个菜单项offsetTop不同的菜单均为超出父级的宽度的菜单。截取这部分菜单放到展开项里。
js代码

import { defineComponent,computed,ref,onMounted,nextTick} from "vue"
import styles from  './index.module.scss';
export default defineComponent({
    setup(props:any) {
        const tabList = ref([{
            name: "首页",
            path: "/",
        },{
            name: "菜单一",
            path: "/",
        },{
            name: "菜单二",
            path: "/",
        },{
            name: "菜单三",
            path: "/",
        },{
            name: "菜单四",
            path: "/",
        },{
            name: "菜单五",
            path: "/",
        },{
            name: "菜单六",
            path: "/",
        },{
            name: "菜单七",
            path: "/",
        },{
            name: "菜单八",
            path: "/",
        },{
            name: "菜单九",
            path: "/",
        },{
            name: "菜单十",
            path: "/",
        }]);
        const expandMenu=ref<any>([])
        const activeMenu = ref<number>(0);
        const getTabIndex=function(children:any,len_:number,firstChildTop:number){
            for (let i = 1; i < len_; i++) {
                if (children[i].offsetTop>firstChildTop) {
                    return i
                }
            };
        };
        onMounted(() => {
            nextTick(() => {
                try{
                    let parent:any = document.getElementById('layout3-head-menu');
                    let children = parent.children;
                    let firstChildTop = children[0].offsetTop;
                    let len_=children.length;
                    let index_:any=getTabIndex(children,len_,firstChildTop);
                    if(index_>0){
                        expandMenu.value=tabList.value.slice(index_);
                    }else{
                        expandMenu.value=[];
                    };
                    if(len_>2&&firstChildTop){
                        window.onresize = () => {
                            let index_:any=getTabIndex(children,len_,firstChildTop);
                            if(index_>0){
                                expandMenu.value=tabList.value.slice(index_);
                            }else{
                                expandMenu.value=[];
                            };
                        };
                    };
                }catch (e) {}
            });
        });
        return () => (<>
            <div class={styles.layout3Head}>
                <div class={styles.layout3Menu}>
                    <div class={styles.layout3MenuCon}>
                        <div class={styles.layout3HeadMenu} id="layout3-head-menu">
                            {
                                tabList.value.map((item:any,index:number) => {
                                    return (<>
                                        <div class={[styles.layout3HeadMenuItem,activeMenu.value==index?styles.layout3HeadMenuItemActive:'']} 
                                            onClick={() => {
                                                activeMenu.value = index;
                                            }}
                                        >
                                            {item.name}
                                        </div>
                                    </>)
                                })
                            }
                        </div>
                        <div class={styles.layout3HeadFun}>
                            {
                                expandMenu.value.length>0?<div class={styles.layout3MenuExpand}>
                                    <el-dropdown v-slots={{
                                        default: () => <>
                                            <el-button link>展开{}</el-button>
                                        </>,
                                        dropdown: () => <el-dropdown-menu>
                                            {
                                                expandMenu.value.map((item:any,index:number) => {
                                                    return (<>
                                                        <el-dropdown-item>{item.name}</el-dropdown-item>
                                                    </>)
                                                })
                                            }
                                        </el-dropdown-menu>
                                    }}>
                                    </el-dropdown>
                                </div>:<></>
                            }
                        </div>
                    </div>
                </div>
            </div>
        </>)
    }
})

css


.layout3-menu{
    width:100%;
    height: 60px;
    display: flex;
    align-items: center;
    .layout3-menu-con{
        flex-grow: 1;
        background: #fff;
        display: flex;
        height: 100%;
        padding: 0 20px;
        box-sizing: border-box;
        align-items: center;
        .layout3-head-menu{
            color: #333333;
            font-size: 14px;
            height: 32px;
            overflow: hidden;
            .layout3-head-menu-item{
                padding: 4px 18px;
                cursor: pointer;
                margin-right: 12px;
                float: left;
            }
            .layout3-head-menu-item-active{
                background: #EFF4FF;
                border-radius: 16px;
                color: #3D7AFA;
            }
        }
        .layout3-head-fun{
            margin-left: auto;
            display: flex;
            align-items: center;
        }
        .layout3-menu-expand{
            margin-right: 12px;
            cursor: pointer;
        }
    }
}

### Vue3后台管理系统中实现头部一级菜单和左侧二级菜单的功能 在Vue3后台管理系统中,可以通过动态加载菜单的方式实现头部的一级菜单以及左侧的二级菜单功能。以下是具体的实现方式: #### 动态加载菜单数据 通过`axios`或其他HTTP库向服务器发送请求,获取菜单结构的数据并存储到组件的状态中。 ```javascript <script setup> import { ref, onMounted } from &#39;vue&#39;; import axios from &#39;axios&#39;; const menuList = ref([]); onMounted(async () => { try { const response = await axios.get(&#39;/api/menus&#39;); if (response.data.meta.status === 200) { menuList.value = response.data.data; } } catch (error) { console.error(&#39;Failed to fetch menus:&#39;, error); } }); </script> <template> <div v-for="menu in menuList" :key="menu.id"> {{ menu.title }} </div> </template> ``` 上述代码展示了如何从API接口获取菜单数据,并将其保存至`menuList`变量中[^1]。 #### 创建顶部导航栏(一级菜单) 可以利用`v-for`指令遍历一级菜单项,并绑定点击事件来切换当前选中的菜单项。 ```html <nav class="header-menu"> <ul> <li v-for="(item, index) in topMenus" :key="index" @click="handleTopMenuClick(item)"> {{ item.name }} </li> </ul> </nav> ``` 其中,`topMenus`是从后端返回或者手动定义好的数组对象集合[^2]。 #### 构建侧边栏子菜单(二级菜单) 当某个顶级分类被激活时,则显示其下属的所有次级选项作为侧面板上的链接条目。 ```html <aside class="sidebar"> <ul v-if="activeSubMenu && activeSubMenu.children.length > 0"> <li v-for="(subItem, subIndex) in activeSubMenu.children" :key="subIndex" @click="navigateTo(subItem.url)"> {{ subItem.label }} </li> </ul> </aside> ``` 这里假设每个顶层节点都有可能携带一个名为children属性的列表字段,该字段包含了所有的第二层路径描述信息[^3]。 以上就是基于Vue框架构建具有响应式特性的多层级导航系统的简单介绍与实践案例分享。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不要动我代码啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值