超详细教程实现Vue底部导航栏TabBar

目录
  • 项目介绍:
  • 项目目录:
  • TabBar效果预览:
  • TabBar实现思路
    • 一、如果在下方有一个单独的TabBar组件,如何封装
    • 二、TabBar中现实的内容由外界决定。
    • 三、自定义TabBarItem,可以传入图片和文字
  • 项目文件目录建立
  • 文件目录介绍
  • 文件起别名代码
  • App.vue代码
  • MainTabBar.vue代码
  • TabBar.vue代码
  • TabBarItem.vue代码
  • index.js路由配置代码
  • home.vue代码
  • category.vue代码
  • profile.vue代码
  • cart.vue代码
  • Base.css代码
  • img图片资源
  • 总结:
  • 主要难点:

项目介绍:

需求:要求tabbar中的文字可动态更改,文字对应的图片动态更改动态增加,文字颜色对应更改,TabBarItem的图片动态更改和增加,整个项目灵活化,利用插槽,路由,父子组件的值传递,利用$router实现点击item就会显示对应的页面。综合性极强,项目开发中遇到类似项目,只需复制其中主要代码即可搭建项目的大体框架。

项目目录:

TabBar效果预览:

TabBar实现思路

一、如果在下方有一个单独的TabBar组件,如何封装

  1. 自定义tabbar组件,在APP中使用。
  2. 让TabBar处于底部,并且设置相关的样式。

二、TabBar中现实的内容由外界决定。

  1. 定义插槽。
  2. flex布局评分TabBar。

三、自定义TabBarItem,可以传入图片和文字

  1. 自定义tabbarItem,并且定义两个插槽:图片,文字。
  2. 给两个插槽外层包装div,用于设置样式。
  3. 填充插槽,实现底部TabBar的效果。

方法可行,动手实现,首先介绍一下目录

项目文件目录建立

文件目录介绍

我建立一个views文件夹,里面建立五个文件,五个文件里面包含了五个vue文件,分别对应着导航栏下的每个按钮。

在assets下建立css和img文件夹,放置tabbar按钮所需的图片和基础类

在component文件夹中建立一个MainTabBar.vue文件和tabbar文件夹,tabbar文件夹里放置MainTabBar的子组件和各种插槽关联文件。

router文件夹下的index文件配置路由文件

main.js是项目的入口文件,项目中所有的页面都会加载main.js,所以main.js,主要有三个作用:

  • 实例化VUE
  • 放置项目中经常会用到的插件和CSS样式,例如网络请求axios和vue-resource,图片懒加载模块:vue-;azyload
  • 存储全局变量例如基本信息等

各个文件夹中的代码实现

第一步、文件很多,引用会常常带来404错误,这里开始先建立文件别名,vue建立文件别名详解

找到resolve对象,在alias中写入各个文件的别名:

文件起别名代码

代码:

resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      '@': resolve('src'),
      'assets': resolve('src/assets'),
      'components': resolve('src/components'),
      'views': resolve('src/views'),
    }
  },

App.vue代码

App.vue中引用MainTabBar组件和各个tabbaritem对应的文件:

<template>
  <div id="app">
    <router-view></router-view>
    <main-tab-bar></main-tab-bar>
  </div>
</template>
<script type="module">
import MainTabBar from 'components/MainTabBar'
export default {
  name: 'App',
  components:{
    MainTabBar
  }
}
</script>

<style>
  @import "assets/css/base";
</style>

MainTabBar.vue代码

MainTabBar组件代码:要求组件满足可修改TabBarItem的个数,颜色,文字,等都是动态的。需要创建各类插槽。

<template>
   <div>
       <tab-bar>
      <tab-bar-item path="/home" activeColor="purple">
        <img slot="item-icon" src="~assets/img/tabbar/shouye.png" alt="" >
        <img slot="item-icon-active" src="~assets/img/tabbar/shouye.active.png" alt="">
        <div slot="item-text">首页</div>
      </tab-bar-item>
      <tab-bar-item path="/category" activeColor="purple">
         <img slot="item-icon" src="~assets/img/tabbar/fenlei.png" alt="">
      <img slot="item-icon-active" src="~assets/img/tabbar/fenlei.active.png" alt="">
         <div slot="item-text">分类</div>
      </tab-bar-item>
      <tab-bar-item path="/cart" activeColor="purple">
         <img slot="item-icon" src="~assets/img/tabbar/gouwuche.png" alt="">
         <img slot="item-icon-active" src="~assets/img/tabbar/gouwuche.active.png" alt="">
        <div slot="item-text">购物车</div>
      </tab-bar-item>
      <tab-bar-item path="/profile" activeColor="purple">
         <img slot="item-icon" src="~assets/img/tabbar/wode.png" alt="">
         <img slot="item-icon-active" src="~assets/img/tabbar/wode.active.png" alt="">
        <div slot="item-text">我的</div>
      </tab-bar-item>
    </tab-bar>
   </div>
</template>

<script>
import TabBar from 'components/tabbar/TabBar'
import TabBarItem from 'components/tabbar/TabBarItem'
export default {
    name:"MainTabBar",
    components:{
        TabBar,
        TabBarItem
    }
}
</script>

<style>

</style>

TabBar.vue代码

TabBar.vue文件,改文件为MainTabBar.vue中的子组件:

<template>
    <div id="tab-bar">
      <slot></slot>
    </div>
</template>
<script>
export default {
    name:'TabBar'
}
</script>

<style>

</style>

TabBarItem.vue代码

TabBarItem.vue为MainTabBar.vue的子组件

<template>
  <div class="tab-bar-item" @click="itemClick">
     <div v-if="!isActive">
       <slot name="item-icon"></slot>
     </div>
     <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:'red'
      }
    },
    data(){
        return {
           // isActive:true
        }
    },
    computed:{
      isActive(){
        //判断
        //return this.$route.path.indexOf(this.path) !== -1
        //return this.$route.path === this.path
        return this.$route.path.indexOf(this.path)?false:true
      },
      activeStyle(){
        return this.isActive?{color:this.activeColor}:{}
      }
    },
    methods:{
      itemClick(){
        this.$router.replace(this.path)
      }
    }

}
</script>

<style>
     #tab-bar{
    display: flex;

  }
  #tab-bar{
    background-color: #f6f6f6;
    border-top: 2px #ccc;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    box-shadow:0px -1px 1px rgba(100,100,100,.2) ;
  }
  .tab-bar-item{
    flex: 1;
    text-align: center;
    height: 49px;
    font-size: 14px;
  }
 .tab-bar-item img{
     width: 24px;
     height: 24px;
     margin-top: 3px;
     vertical-align: middle;
     margin-bottom: 3px;
 }
 .active{
     color: red;
 }
</style>

index.js路由配置代码

router文件夹下的index文件为路由的配置:

import Vue from 'vue'
import VueRouter from 'vue-router';
const Home = () => import('views/home/home')
const Category = () => import('views/category/category')
const Cart = () => import('views/cart/cart')
const Profile = () => import('../views/profile/profile')

//1.安装插件
Vue.use(VueRouter)

//2.创建路由对象
const routes = [
    {
        path:'',
        redirect:'/home'
    },
    {
        path:'/home',
        component:Home
    },
    {
        path:'/category',
        component:Category
    },
    {
        path:'/cart',
        component:Cart
    },
    {
        path:'/profile',
        component:Profile
    }
]
const router  = new VueRouter({
    routes,
    mode:'history'
})

//3.导出router
export default router

views中的home代码,cart代码,profile代码,category代码:

home.vue代码

<template>
    <h2>首页</h2>
</template>

<script>
export default {
    name:"Home"
}
</script>

<style>

</style>

category.vue代码

<template>
    <h2>分类</h2>
</template>

<script>
export default {
    name:"Home"
}
</script>

<style>

</style>

profile.vue代码

<template>
    <h2>个人</h2>
</template>

<script>
export default {
    name:"Home"
}
</script>

<style>

</style>

cart.vue代码

<template>
    <h2>购物车</h2>
</template>

<script>
export default {
    name:"Home"
}
</script>

<style>

</style>

Base.css代码

CSS文件下的base.css内容:

body{
    padding: 0px;
    margin: 0px;
}

img图片资源

实现完成~

总结:

项目综合性很大,其中有插槽,路由,子组件父组件的值得传递,别名设置的各种知识。
项目动态内容:tabbar的文字,图片,颜色都可以动态改变,下次类似项目直接可以引用这些文件。

主要难点:

一、当点击到对应的TabBarItem上的时候改变图片颜色,文字颜色,这里是用当前的活跃路由和传过来的地址是否对应,如果对应就会变为true返货来为false:

computed:{
      isActive(){
        //判断
        return this.$route.path.indexOf(this.path)?false:true
      },
      activeStyle(){
        return this.isActive?{color:this.activeColor}:{}
      }
    },
    methods:{
      itemClick(){
        this.$router.replace(this.path)
      }
    }

上面的代码还有其他方法:

       return this.$route.path.indexOf(this.path) !== -1
       return this.$route.path === this.path

二、父组件传值问题,父组件传过来对应的文件路径,对应的字体颜色,子组件接受并使用:

export default {
    name:"TabBarItem",
    props:{
      path:String,
      activeColor:{
        type:String,
        default:'red'
      }
    },
    data(){
        return {}
    },

项目完成~

到此这篇关于Vue实现TabBar底部导航栏的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解Vue底部导航栏组件

    不多说直接上代码 BottomNav.vue: <template> <div class="footer"> <div v-for='(item,index) of items' :class='[item.cls,{on:index === idx}]' @click="$router.push(item.push)"> <img :src="index===idx?item.iconSelect:item.i

  • vue自定义底部导航栏Tabbar的实现代码

    如图所示,要完成类似的一个底部导航切换. 首先.我们需要分为5个大的VUE文件.可以根据自己的习惯来放在不同的位置. 我将5个主要的vue文件放在了5个不同的文件夹 然后,在components文件夹里新建Tabbar.vue/以及Item.vue文件 Item.vue文件如下 <template> <div class="itemWarp flex_mid" @click='changePage'> <span v-show='!bol'> <

  • vue.js 底部导航栏 一级路由显示 子路由不显示的解决方法

    最近利用vue第三方UI MuseUI开发webapp,然后在导航栏这里出现了问题,我需要在导航栏上的几个路由上显示底部导航栏,在其他路由上不显示,就这个问题,MuseUI的底部导航栏直接加载在app.vue里面,会每个页面都有导航栏,所以这种方式不可行,后来我真的使出了浑身解数,去MuseUI作者GitHub上面提问,无果,去segmentfault上面提问,无果,去vue官方群提问,无果,在提问之前,我都是经过一番搜索,思考的,但是这些都让我崩溃了.可能出错的地方从路由URL,museUI的

  • 超详细教程实现Vue底部导航栏TabBar

    目录 项目介绍: 项目目录: TabBar效果预览: TabBar实现思路 一.如果在下方有一个单独的TabBar组件,如何封装 二.TabBar中现实的内容由外界决定. 三.自定义TabBarItem,可以传入图片和文字 项目文件目录建立 文件目录介绍 文件起别名代码 App.vue代码 MainTabBar.vue代码 TabBar.vue代码 TabBarItem.vue代码 index.js路由配置代码 home.vue代码 category.vue代码 profile.vue代码 ca

  • 超简单的几行代码搞定Android底部导航栏功能

    超简单,几行代码搞定Android底部导航栏-–应项目需求以及小伙伴的留言,新加了两个方法: 设置底部导航栏背景图片 添加底部导航栏选项卡切换监听事件 底部导航栏的实现也不难,就是下边是几个Tab切换,上边一般是一个FrameLayout,然后FrameLayout中切换fragment. 网上有不少关于Android底部导航栏的文章,不过好像都只是关于下边Tab切的,没有实现Tab与fragment的联动,用的时候还要自己手写这部分代码,对我这个比较懒(据说,懒是程序员的一种美德_#)得程序员

  • vue router仿天猫底部导航栏功能

    首先把天猫的导航贴出来,里面包括精选.品牌.会员.购物车.我五个导航及对应的图标. 分析: 1.图标的获取 进入阿里巴巴矢量图标库,网址  http://www.iconfont.cn. 点击官方图标库,选择天猫图标库,选中放入购物车. 点击添加至项目,点击创建新项目按钮,创建tianmao项目,点击确定. 此时会有查看在线链接和下载至本地两种方式,我选择第一种,因为后期如果要添加小图标的话,只需要重新生成在线链接,然后更新link即可 复制链接到index.html的link标签内,具体为 <

  • vue中使用vuex的超详细教程

    目录 一.适合初学者使用,保存数据以及获取数据 二.模块化(适合有部分基础的人) vuex是使用vue中必不可少的一部分,基于父子.兄弟组件,我们传值可能会很方便,但是如果是没有关联的组件之间要使用同一组数据,就显得很无能为力,那么vuex就很好的解决了我们这种问题,它相当于一个公共仓库,保存着所有组件都能共用的数据. 那么,我们一起来看看vue项目怎么使用它吧.(如果你对vuex有一定了解,不是刚接触的小白,请忽略第一步,直接查看第二步) 一.适合初学者使用,保存数据以及获取数据 1.在sto

  • Spring Boot 员工管理系统超详细教程(源码分享)

    员工管理系统 1.准备工作 资料下载 内含源码 + 笔记 + web素材 源码下载地址: http://xiazai.jb51.net/202105/yuanma/javaguanli_jb51.rar 笔记 素材 源码 1.1.导入资源 将文件夹中的静态资源导入idea中 位置如下 1.2.编写pojo层 员工表 //员工表 @Data @NoArgsConstructor public class Employee { private Integer id; private String l

  • vue实现导航栏效果(选中状态刷新不消失)

    Vue导航栏 用Vue写手机端的项目,经常会写底部导航栏,我这里总结一套比较方便实用的底部导航栏方法,并且可以解决浏览器刷新选中状态消失的问题.也可以选择自适应屏幕.看一下效果,底部的图标全是UI给的选中和未选中样式的图片,根据公司要求,你也可能会用fontsize去写.(全部代码黏贴到本文的最后面了) 1.首先把这些小图片放到src/assets路径下面(自动base64编码) 2.在data()里边定义一个选中对应的变量isSelect,和循环遍历的数组,数组下面放图标对应的文字,和选中,未

  • 微信小程序实战之仿android fragment可滑动底部导航栏(4)

    底部3-5个选项的底部导航栏,目前在移动端上是主流布局之一,因此腾讯官方特地做了,可以通过设置,就可以做出了一个底部的导航栏. 相关教程:微信小程序教程系列之设置标题栏和导航栏(7) 但是通过设置的这个底部的导航栏,功能上比较固定,它必须要设置与它对应的一个页面,而且并不能滑动. 在业务上,有时候会比较限制,并不能完全满足所需. 又例如早前有人拿着UI稿问我,这种广告轮播图的样式,在小程序能不能实现呢? 我当时没有想了下,还不是很确定,因为小程序的轮播图的那几个小点点实在比较普通,样式单一. 因

随机推荐