vue底部菜单实现
实现底部菜单的基本结构
在Vue中实现底部菜单通常需要结合<router-link>和路由配置。以下是一个基础模板结构,使用Vue 3的<script setup>语法和Vue Router:
<template>
<div class="app-container">
<router-view />
<nav class="bottom-menu">
<router-link to="/home" class="menu-item">
<span class="icon">🏠</span>
<span class="label">首页</span>
</router-link>
<router-link to="/discover" class="menu-item">
<span class="icon">🔍</span>
<span class="label">发现</span>
</router-link>
<router-link to="/profile" class="menu-item">
<span class="icon">👤</span>
<span class="label">我的</span>
</router-link>
</nav>
</div>
</template>
<style scoped>
.bottom-menu {
position: fixed;
bottom: 0;
left: 0;
right: 0;
display: flex;
justify-content: space-around;
background: white;
padding: 8px 0;
box-shadow: 0 -2px 10px rgba(0,0,0,0.1);
}
.menu-item {
display: flex;
flex-direction: column;
align-items: center;
text-decoration: none;
color: #666;
}
.router-link-active {
color: #42b983;
}
</style>
动态激活样式处理
为了更灵活地控制激活状态样式,可以在路由配置中添加meta字段:
// router.js
const routes = [
{
path: '/home',
component: Home,
meta: { menuIndex: 0 }
},
{
path: '/discover',
component: Discover,
meta: { menuIndex: 1 }
}
]
然后在组件中使用计算属性判断激活状态:
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
const activeIndex = computed(() => route.meta?.menuIndex ?? -1)
</script>
<template>
<router-link
v-for="(item, index) in menuItems"
:class="{ 'active': index === activeIndex }"
>
</template>
使用UI库快速实现
对于需要快速开发的场景,可以借助UI库如Vant的Tabbar组件:
import { Tabbar, TabbarItem } from 'vant'
<template>
<van-tabbar v-model="active" fixed>
<van-tabbar-item icon="home-o">首页</van-tabbar-item>
<van-tabbar-item icon="search">搜索</van-tabbar-item>
<van-tabbar-item icon="user-o">我的</van-tabbar-item>
</van-tabbar>
</template>
移动端适配技巧
针对不同设备需要处理安全区域,特别是在iOS设备上:
.bottom-menu {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
添加过渡动画提升用户体验:
.menu-item {
transition: all 0.3s ease;
}
.menu-item.active {
transform: translateY(-5px);
}
路由守卫与菜单联动
在路由跳转时同步更新菜单状态:
router.beforeEach((to, from, next) => {
store.commit('setActiveMenu', to.meta.menuIndex)
next()
})
在组件中通过Vuex或Pinia获取当前激活状态:
<script setup>
import { storeToRefs } from 'pinia'
const menuStore = useMenuStore()
const { activeMenu } = storeToRefs(menuStore)
</script>






