Vue实现页面布局栏目组件化

这些都是我根据B站winWeb前端分享的个人空间_哔哩哔哩_Bilibili 的视频再自己动手进行实践的

在实际开发中,我们浏览网页,网页顶部的导航栏Header和侧边的菜单栏Aside,以及底部的footer等内容往往是不发生改变的,如果在每次页面跳转、提交表单后都去重写这部分是很麻烦的,而Element-Plus为我们提供了封装好的标签,让我们能够通过组件化来实现页面的布局。

注意!将这些封装成组件后使用会出现错位的问题

 出现这个问题的原因是封装成组件后,<el-container>中没有了<el-footer>和<el-header>,导致子元素排列方向默认为horizontal,因此可以采用在<el-container>标签中添加direction="vertical"属性即可解决。

构建CommonHeader组件

首先我们在components目录下新建自己的组件vue,首先新建CommonHeader.vue,并使用<template>标签构造模板,在使用Element-Plus难免会用到一些图标icon,Element-Plus提供了很多图标,具体使用方法见Icon 图标 | Element Plus

下面是构造Header的源码

<template>
    <el-header>
        <div class="l-content">
            <el-button size="small">
                <el-icon :size='20'>
                    <Menu />
                </el-icon>
            </el-button>
        </div>
        <div class="r-content">
            <el-dropdown>
                <span class="el-dropdown-link">
                    <img :src="getImageUrl('user')" alt="" class="user">
                </span>
                <template #dropdown>
                    <el-dropdown-menu>
                        <el-dropdown-item>Action 1</el-dropdown-item>
                        <el-dropdown-item>Action 2</el-dropdown-item>
                        <el-dropdown-item>Action 3</el-dropdown-item>
                        <el-dropdown-item disabled>Action 4</el-dropdown-item>
                        <el-dropdown-item divided>Action 5</el-dropdown-item>
                    </el-dropdown-menu>
                </template>
            </el-dropdown>
        </div>
    </el-header>
</template>

<script>
import {defineComponent} from "vue-demi"
export default defineComponent({
    setup() {
        let getImageUrl=(user)=>{
                //使用统一资源定位符来访问项目静态图片
                let userImageUrl=new URL(`../assets/img/${user}.jpg`,import.meta.url);
                return userImageUrl.href;
        }
        return{
            getImageUrl
        };
    }
}) 
</script>

<style lang="less" scoped>
header{
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
}

.r-content{
    .user{
        width: 40px;
        height: 40px;
        border-radius: 50%;
    }
}
</style>

随后我们需要在Main.vue界面中导入我们自建的组件,让其在主页面上显示

<template>
    <el-container direction="vertical">
        <common-header />
        <el-container>
            <el-aside>
                <h3>I am aside</h3>
            </el-aside>
            <el-container>
                <el-main>
                    <router-view></router-view>
                </el-main>
                <el-footer>
                    <h3>I am footer</h3>
                </el-footer>
            </el-container>
        </el-container>
    </el-container>
</template>

<script>
import {defineComponent} from 'vue'
import CommonHeader from '../components/CommonHeader.vue';
export default defineComponent({
    components:{
        CommonHeader
    }
})

在其中使用了Element-Plus库中的图标,并且使用统一资源定位符来访问项目中的静态资源,最后实现顶部Header的组件化。显示效果如下

 构建CommonAside组件

跟之前类似,首先我们在components目录下新建自己的组件vue,我们这里创建CommonAside.vue,菜单的内容数据从list中来,vue中的源代码如下:

<template>
    <el-aside style="width:200px">
        <el-menu 
            class="el-menu-vertical-demo" 
            background-color="gray"
            text-color="white"
            :collapse="false"
            >
            <!-- 从list中获取数据装载成菜单栏 -->
            <el-menu-item
                :index="item.path"
                v-for="item in noChildren()" 
                :key="item.path"
            >
            <component class="icons" :is="item.icon"></component>
            <span>{{item.label}}</span>
            </el-menu-item>
            <el-sub-menu
                :index="item.path"
                v-for="item in hasChildern()" 
                :key="item.path"
            >
            <template #title>
                <component class="icons" :is="item.icon"></component>
                <span>{{item.label}}</span>
            </template>
            <el-menu-item-group>
                <el-menu-item 
                    :index='subItem.path'
                    v-for="(subItem, subIndex) in item.children"
                    :key="subIndex"
                >
                <component class="icons" :is="subItem.icon"></component>
                <span>{{subItem.label}}</span>
                </el-menu-item>
            </el-menu-item-group>
            </el-sub-menu>
        </el-menu>
    </el-aside>
</template>

<script>
export default({
    setup() {
        const list=[
            {
                path:'/user',
                name:'user',
                label:'用户管理',
                icon:'user',
                URL:'UserManage/UserManage'
            },
            {
                label:'其他',
                icon:'location',
                path:'/other',
                children:[
                    {
                        path:'/page1',
                        name:'page1',
                        label:'页面1',
                        icon:'setting',
                        url:'Other/PageOne'
                    },
                    {
                        path:'/page2',
                        name:'page2',
                        label:'页面2',
                        icon:'setting',
                        url:'Other/PageTwo'
                    }
                ]
            }
        ];

        //对list进行处理
        const noChildren=()=>{
            return list.filter((item)=>!item.children);
        };

        const hasChildern=()=>{
            return list.filter((item)=>item.children);
        }

        return {
            noChildren,
            hasChildern
        };
    },
})
</script>

<style lang="less" scoped>
.icons {
    width: 20px;
    height: 20px;
}
    
</style>

在这里面我们使用了<el-menu>标签,使用该标签我们可以构造一个左侧的菜单栏。同样我们需要去Main.vue界面中进行导入,源代码如下:

<template>
    <el-container direction="vertical">
        <common-header class="common-header" />
        <el-container>
            <common-aside class="common-aside" />
            <el-container>
                <el-main>
                    <router-view></router-view>
                </el-main>
                <el-footer>
                    <h3>I am footer</h3>
                </el-footer>
            </el-container>
        </el-container>
    </el-container>
</template>

<script>
import {defineComponent} from 'vue'
import CommonHeader from '../components/CommonHeader.vue';
import CommonAside from '../components/CommonAside.vue';
export default defineComponent({
    components:{
        CommonHeader,
        CommonAside
    }
})

之后的运行效果如下图所示:

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值