基于vue组件思想的移动端导航栏 —— TabBar

用vue CLI 3.0搭建的项目结构,组件目录结构如图,做个笔记📒。

在这里插入图片描述

封装TabBar组件:

在这里插入图片描述

组件目录结构:


MainTabBar.vue —> TabBar.vue —> TabBarItem.vue

思路就是,TabBar 里的内容由插槽决定,然后用 flex 布局平分TabBar。

然后自定义四个 item ,可以传入图片和文字,item 里的图片和文字用插槽来实现,插槽外再用 div 包装,用来设置样式。

插槽就相当于占位符。


1、TabBarItem.vue 页面中:

这个组件主要为TabBar内部的子组件,项目中需要放几个就可以放几个,并且点击的时候将会跳转到对应的路由当中。

<template>   
  <div class="tab-bar-item">
     <!-- icon -->
     <div> <slot name="item-icon"> </slot> </div>
     <!-- 活跃的icon -->
     <div> <slot name="item-icon-active"> </slot> </div>
     <!-- 文字 -->
    <div> <slot name="item-text"> </slot> </div>   
 </div> 
</template> 

使用组件 TabBarItem 往里面填充内容时,就利用插槽来实现:slot = " " :

2、MainTabBar.vue页面中使用:

 <tab-bar>
    <tab-bar-item>
       <img slot="item-icon" src="@/assets/images/tabbar/home.svg" alt="" />
       <img
           slot="item-icon-active"
           src="@/assets/images/tabbar/home_active.svg"
           alt=""/>
       <div slot="item-text">首页</div>
    </tab-bar-item>
</tab-bar>

占位符插槽使用很简单,直接填充名字slot=“ ”,然后往里面填充内容。


3、TabBar.vue 页面完整内容,只需要添加一个插槽,用来填充TabBarItem:

<template>
    <div id="tab-bar">
        <slot></slot>
    </div>
</template>


4、TabBarItem.vue 页面中完整内容:

<template>
  <div class="tab-bar-item" @click="itemClick">
      <!-- icon -->
      <div v-if="!isActive"><slot name="item-icon"> </slot></div>
      <!-- 活跃的icon -->
      <div v-else><slot name="item-icon-active"> </slot></div>
      <!-- 文字 -->
      <div :style="activeStyle"><slot name="item-text"> </slot></div>
  </div>
</template>

<script>
export default {
  name: "TabBarItem",
  props: {
      path: String,
      activeColor: {
          type: String,
          default: "#fc5979",
      },
  },
  computed: {
      isActive() {
          return this.$route.path.indexOf(this.path) !== -1;
      },
      activeStyle() {
          return this.isActive ? { color: this.activeColor } : {};
      },
  },
  methods: {
      itemClick() {
          this.$router.replace(this.path);
      },
  },
};
</script>

<style lang="scss" scoped>
.tab-bar-item {
    flex: 1;
    text-align: center;
    height: 49px;
    font-size: 14px;
    img {
        width: 24px;
        height: 24px;
        margin-top: 3px;
        vertical-align: middle;
        margin-bottom: 2px;
    }
}
</style>


5、MainTabBar.vue 页面中完整内容:

只展示了一个item

<template>
   <tab-bar>
      <tab-bar-item path="/home" activeColor="#fc5979">
         <img slot="item-icon" src="@/assets/images/tabbar/home.svg" alt="" />
         <img
             slot="item-icon-active"
             src="@/assets/images/tabbar/home_active.svg"
             alt=""/>
         <div slot="item-text">首页</div>
      </tab-bar-item>
   </tab-bar>
</template>

<script>
import TabBar from "@/components/common/tabbar/TabBar";
import TabBarItem from "@/components/common/tabbar/TabBarItem";

export default {
    name: "MainTabBar",
    components: {
        TabBar,
        TabBarItem,
    },
};
</script>


涉及到的组件传值:

MainTabBar是父组件,TabBarItem为子组件,父组件需要传两个值:1.点击tab切换的路由 path 2.点击tab切换活跃状态 activeColor。

TabBarItem组件中,点击切换活跃的样式,父组件点击,然后props传递给item子组件。在computed计算属性中。返回不同的布尔值。来做底部图片的显示隐藏。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3中可以通过自定义组件实现底部导航栏的灵活组件。以下是一个简单的实现示例: 1. 创建一个TabBar组件,用于展示底部导航栏: ```vue <template> <div class="tab-bar"> <slot></slot> </div> </template> <script> export default { name: "TabBar", }; </script> <style scoped> .tab-bar { display: flex; justify-content: space-around; align-items: center; position: fixed; bottom: 0; left: 0; right: 0; height: 50px; background-color: #fff; box-shadow: 0 -3px 5px rgba(0, 0, 0, 0.1); } </style> ``` 2. 在TabBar组件使用slot插槽,用于接收底部导航栏的子组件。例如: ```vue <template> <div class="tab-bar"> <slot></slot> </div> </template> <script> export default { name: "TabBar", }; </script> <style scoped> .tab-bar { display: flex; justify-content: space-around; align-items: center; position: fixed; bottom: 0; left: 0; right: 0; height: 50px; background-color: #fff; box-shadow: 0 -3px 5px rgba(0, 0, 0, 0.1); } </style> ``` 3. 创建底部导航栏组件,例如TabBarItem。在TabBarItem中可以定义图标、文字和点击事件等属性。例如: ```vue <template> <div class="tab-bar-item" :class="{ active: active }" @click="handleClick"> <i :class="icon"></i> <span>{{ title }}</span> </div> </template> <script> export default { name: "TabBarItem", props: { icon: { type: String, required: true, }, title: { type: String, required: true, }, active: { type: Boolean, required: true, }, }, methods: { handleClick() { this.$emit("click"); }, }, }; </script> <style scoped> .tab-bar-item { display: flex; flex-direction: column; align-items: center; font-size: 12px; color: #666; } .tab-bar-item i { font-size: 20px; margin-bottom: 2px; } .tab-bar-item.active { color: #007aff; } </style> ``` 4. 在父组件使用TabBarTabBarItem组件。例如: ```vue <template> <div> <router-view /> <TabBar> <TabBarItem v-for="(tab, index) in tabs" :key="index" :icon="tab.icon" :title="tab.title" :active="index === activeIndex" @click="activeIndex = index" /> </TabBar> </div> </template> <script> import TabBar from "@/components/TabBar.vue"; import TabBarItem from "@/components/TabBarItem.vue"; export default { name: "App", components: { TabBar, TabBarItem, }, data() { return { tabs: [ { icon: "icon-home", title: "首页", }, { icon: "icon-category", title: "分类", }, { icon: "icon-cart", title: "购物车", }, { icon: "icon-person", title: "个人中心", }, ], activeIndex: 0, }; }, }; </script> ``` 在父组件使用TabBarTabBarItem组件,通过循环遍历tabs数组,动态生成底部导航栏组件TabBarItem,并通过activeIndex属性控制当前激活的子组件。当子组件被点击时,通过click事件向父组件发送消息,触发activeIndex的变化,从而实现底部导航栏的切换。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值