前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TabBar(标签栏)实现思路

TabBar(标签栏)实现思路

作者头像
名字是乱打的
发布2021-12-23 17:34:12
1.3K0
发布2021-12-23 17:34:12
举报
文章被收录于专栏:软件工程软件工程

一 . TabBar需求即要求如图所示

二. TabBar实现思路

代码语言:javascript
复制
1. 在下方有一个单独的TabBar组件
- 自定义TabBar组件,在APP中使用
- 让TabBar出于底部,并且设置相关的样式

2.TabBar中显示的内容由外界决定
- 定义插槽
- flex布局平分TabBar

3.自定义TabBarItem,可以传入 图片和文字
- 定义TabBarItem,并且定义两个插槽:图片、文字。
- 给两个插槽外层包装div,用于设置样式。
- 填充插槽,实现底部TabBar的效果

4.传入 高亮图片
定义另外一个插槽,插入active-icon的数据
定义一个变量isActive,通过v-show来决定是否显示对应的icon

5.TabBarItem绑定路由数据
安装路由:npm install vue-router —save
完成router/index.js的内容,以及创建对应的组件
main.js中注册router
APP中加入<router-view>组件

6.点击item跳转到对应路由,并且动态决定isActive
监听item的点击,通过this.$router.replace()替换路由路径
通过this.$route.path.indexOf(this.link) !== -1来判断是否是active

7.动态计算active样式
封装新的计算属性:this.isActive ? {'color': 'red'} : {}
实现效果

代码结构,以及普通的页面组件

代码

tabbar

代码语言:javascript
复制
<template>
 <div id="tab-bar">
   <slot></slot>
 </div>
</template>

<script>
 export default {
   data () {
     return {
        
     }
   },
   components: {
   }
 }
</script>

<style>
  #tab-bar{
    display: flex;
    background: #f6f6f6;
    position: fixed;
    padding: 0px;
    margin: 0px;
    left: 0;
    right: 0;
    bottom: 0;
  }


 
</style>

tabbaritem

代码语言:javascript
复制
<template>
  <div class="tab-bar-item" @click="clickTabBarItem()">
    <div v-if="!active">
      <slot name="item-icon" />
    </div>
    <div v-if="active">
      <slot name="item-icon-active" />
    </div>
    <div :style="textStyle">
      <slot name="item-text" />
    </div>
  </div>
</template>

<script>
export default {
  props: {
    path: String,
    color: {
      type: String,
      default: "red"
    }
  },
  data() {
    return {};
  },
  methods: {
    clickTabBarItem() {
      this.active = true;
      this.$router.replace(this.path);
    }
  },
  computed: {
    active: {
      get: function() {
        //判断当前活跃路由路径里有没有本组件名
        return !(this.$route.path.indexOf(this.path) == -1);
      },
      // setter
      set: function(newValue) {}
    },
    textStyle: {
      get: function() {
        return this.active ? { color: this.color } : {};
      },
      // setter
      set: function(newValue) {}
    }
  },
  components: {}
};
</script>

<style>
.tab-bar-item {
  flex: 1;
  text-align: center;
  height: 49px;
  box-shadow: 0 -3px 1px rgba(100, 100, 100, 0.2);
  font-size: 14px;
}

.tab-bar-item img {
  height: 24px;
  width: 24px;
  margin-top: 3px;
  vertical-align: 0px;
}
</style>

router里的index.js

代码语言:javascript
复制
import vue from "vue"
import VueRouter from "vue-router"


vue.use(VueRouter)

export default new VueRouter({
    mode: 'history',
    routes: [
        {
            path: '/',
            redirect:'/home'
        }, {
            path: '/home',
            component: () => import('../pages/home/Home')
        }, {
            path: '/profile',
            component: () => import('../pages/profile/Profile')
        }, {
            path: '/shopcar',
            component: () => import('../pages/shopcar/Shopcar')
        }, {
            path: '/catagory',
            component: () => import('../pages/catagory/Catagory')
        }
    ]
})

毫无新意的main.js

代码语言:javascript
复制
import Vue from 'vue'
import App from './App'
import router from './router'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  render: h => h(App)
})

汇总的app.vue

代码语言:javascript
复制
<template>
  <div id="app">
   <router-view/> 

    <tab-bar>
      <tab-bar-item path="/home"  color='red'>
        <img src="./assets/img/tabbar/home.svg" slot="item-icon" />
        <img src="./assets/img/tabbar/home_active.svg" slot="item-icon-active" />
        <div slot="item-text">首页</div>
      </tab-bar-item>


      <tab-bar-item path="/catagory"  color='yellow'>
        <img src="./assets/img/tabbar/category.svg" slot="item-icon" />
        <img src="./assets/img/tabbar/category_active.svg" slot="item-icon-active" />
        <div slot="item-text">分类</div>
      </tab-bar-item>


      <tab-bar-item path="/shopcar" color='blue'>
        <img src="./assets/img/tabbar/shopcart.svg" slot="item-icon" />
        <img src="./assets/img/tabbar/shopcart_active.svg" slot="item-icon-active" />
        <div slot="item-text">购物车</div>
      </tab-bar-item>


      <tab-bar-item path="/profile"  color='black'>
        <img src="./assets/img/tabbar/profile.svg" slot="item-icon" />
        <img src="./assets/img/tabbar/profile_active.svg" slot="item-icon-active" />
        <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: "App",
  components: {
    TabBar,
    TabBarItem
  }
};
</script>

<style>
</style>
思考:

一个小demo的学习,似乎让我稍微理解了一下组件化开发过程中的封装和复用思想. 钩子函数和路由里的几个函数在组件间进行交互时候似乎显得尤其重要.

害,咱的VsCode咋感觉代码提示这么差劲呢?我TM都敲完了你都没识别我用的函数...下了vuehelper也不顶用

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020/11/16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一 . TabBar需求即要求如图所示
  • 二. TabBar实现思路
    • 实现效果
      • 代码结构,以及普通的页面组件
        • 代码
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档