vue 在移动端怎么使用公共布局

在移动端一般都是 navbar + main + tabbar 这种布局,怎么把navbar 和 tabbar 实现公用

目前我的做法是直接在 App.vue 里面使用 navbar 和 tabbar 组件,然后通过路由的 meta 信息来控制显示隐藏

<template>
    <div id="app">
        <navbar v-if="navbarVisible" />
        <router-view />
        <tabbar v-if="tabbarVisible" />
    </div>
</template>
<script>
    export default {
        computed: {
            navbarVisible() {
                const { meta } = this.$route
                return meta && meta.navbarVisible
            },
            tabbarVisible() {
                const { meta } = this.$route
                return meta && meta.tabbarVisible
            }
        }
    }
</script>

路由配置:

const routes = [
    {
        path: '/home',
        component: () => import('@/views/home'),
        meta: {
            navbarVisible: true,
            tabbarVisible: true
        }
    }
]

其他的方法
1、封装一个 layout 组件,通过插槽嵌入 main 内容区域,然后navbar 和 tabbar 通过 props 来控制,layout.vue 大概如下

<template>
    <div class="layout">
        <navbar v-if="navbarVisible" />
        <slot></slot>
        <tabbar v-if="tabbarVisible" />
    </div>
</template>
<script>
    export default {
        props: {
            navbarVisible: {
                type: Boolean,
                default: true
            },
            tabbarVisible: {
                type: Boolean,
                default: true
            }
        }
    }
</script>

使用 layout 组件:

<template>
    <layout navbar-visible :navbar-visible="false">
        <div>这里是内容</div>
    <layout>
</template>

2、通过嵌套路由,layout 组件

<template>
    <div class="layout">
        <navbar />
        <router-view />
        <tabbar />
    </div>
</template>

路由配置:

import Layout from '@/layouts/layout'
const routes = [
    {
        path: '/home',
        component: Layout,
        children: [
            path: '',
            component: () => import('@/views/home')
        ]
    }
]

这样通过嵌套路由用不同的布局组件,也可以实现
大家都是用的哪种啊,还是说有更好的方式

阅读 3.5k
2 个回答

我喜欢用第一种,而且我一般情况下会定义两个数组。这样后期改需求的时候增加,减少很方便,而且哪些页面有头部,哪些页面有尾部看的很清晰。

<div id="app">
    <navbar v-if="navbarList.includes(route.name)" />
    <router-view />
    <tabbar v-if="tabbarList.includes(route.name)" />
</div>
<script>
    export default {
        data() {
            return {
                tabbarList: ['a', 'c', 'd', 'e'],
                navbarList: ['a', 'b', 'c']
            }
        }
    }
</script>

两种本质是一样的,只是第一种你把layout相关逻辑放在了app组件里处理了。建议第二种。从持续迭代方面考虑,应该使组件尽量满足单一原则。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题