tabbar
2022/3/20 23:27:57
本文主要是介绍tabbar,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
TabBar 的实现功能
TabBar实现思路
- 如果在下方有一个单独的Tabbar组件,你如何封装
- 自定义TabBar组件,在APP中使用
- 让TabBar出于底部,并且设置相关的样式
- TabBar中显示的内容有外界决定
- 定义插槽
- flex布局平分TabBar
- 自定义TabBarItem,可以传入图片和文字
- 定义TabBarItem,并且定义两个插槽:图片、文字。
- 给两个插槽外层包装div,用于设置样式。
- 填充插槽,实现底部TabBar的效果
- 传入高亮图片
- 定义另外一个插槽,插入active-icon的数据
- 定义一个变量isActive,通过v-show来决定是否显示对应的icon
- TabBarItem绑定路由数据
- 安装路由:npm install vue-router —save
- 完成router/index.js的内容,以及创建对应的组件
- main.js中注册router
- APP中加入
<router-view>
组件
- 点击Item跳转对应路由,并动态决定isActive
- 监听item的点击,通过
this.$router.replace()
替换路由路径 - 通过
this.$route.path.indexOf(this.link) !== -1
来判断是否是active
- 监听item的点击,通过
- 动态计算active样式并且不同的分类显示不同的颜色
- 封装新的计算属性:
this.isActive ? {'color': 'red'} : {}
- 封装新的计算属性:
- 动态添加数据并进行切换
- 将数据定义到data中tabList数组中[{label:’’,itemIcon:",itemIconActive:"",path:"",activeColor:’’}]
具体实现
1.新建项目
vue create demo
2.新建目录
base.css
body{ margin: 0; padding: 0; }
在App.vue文件中,我们在<style>
里@import "./common/style/base.css";
来引入css样式
在main.js中用require('./common/style/base.css')
引入
3.TabBar页面搭建
App.vue代码
<template> <div id="app"> <div id="tab-bar"> <div class="tab-bar-item"> <img src="./common/img/tabbar/home.svg" alt=""> <div>首页</div> </div> <div class="tab-bar-item"> <img src="./common/img/tabbar/category.svg" alt=""> <div>分类</div> </div> <div class="tab-bar-item"> <img src="./common/img/tabbar/shopcart.svg" alt=""> <div>购物车</div> </div> <div class="tab-bar-item"> <img src="./common/img/tabbar/profile.svg" alt=""> <div>我的</div> </div> </div> </div> </template> <script> export default { name: 'App', } </script> <style> @import url("~@/common/style/base.css"); #tab-bar { display: flex; background-color: #f6f6f6; position: fixed; left: 0; right: 0; bottom: 0; box-shadow: 0 -1px 1px rgba(100, 100, 100, 100); } .tab-bar-item { flex: 1; text-align: center; height: 49px; } .tab-bar-item img { width: 24px; height: 24px; } .tab-bar-item { flex: 1; text-align: center; height: 49px; font-size: 14px; } .tab-bar-item img { width: 24px; height: 24px; margin-top: 3px; /*去掉图片下面多出来的3像素*/ vertical-align: middle; } </style>
4.拆分成TabBar和TabBarItem并进行封装
tabbar.vue
<template> <div id="tab-bar"> <slot></slot> </div> </template> <script> </script> <style> #tab-bar { display: flex; background-color: #f6f6f6; position: fixed; left: 0; right: 0; bottom: 0; box-shadow: 0 -1px 1px rgba(100, 100, 100, 100); } </style>
tabbarItem.vue
<template> <router-link class="tab-bar-item" :tag="tags" :to="path"> <slot name="item-icon"></slot> <slot name="item-text"></slot> </router-link> </template> <script> export default { props: { path: { type: String, default: "", }, tags:{ type:String, default:"div" } }, } </script> <style> .tab-bar-item { flex: 1; text-align: center; height: 49px; } .tab-bar-item img { width: 24px; height: 24px; } .tab-bar-item { flex: 1; text-align: center; height: 49px; font-size: 14px; } .tab-bar-item img { width: 24px; height: 24px; margin-top: 3px; /*去掉图片下面多出来的3像素*/ vertical-align: middle; } </style>
app.vue
<template> <div id="app"> <tabBar> <tabBarItem path="/home" > <img slot="item-icon" src="~@/common/img/tabbar/home.svg" alt="" /> <div slot="item-text">首页</div> </tabBarItem> <tabBarItem path="/category" > <img slot="item-icon" src="~@/common/img/tabbar/category.svg" alt="" /> <div slot="item-text">分类</div> </tabBarItem> <tabBarItem path="/cart"> <img slot="item-icon" src="~@/common/img/tabbar/shopcart.svg" alt="" /> <div slot="item-text">购物车</div> </tabBarItem> <tabBarItem path="/my"> <img slot="item-icon" src="~@/common/img/tabbar/profile.svg" alt="" /> <div slot="item-text">我的</div> </tabBarItem> </tabBar> </div> </template> <script> import tabBar from '@/page/tabbar/tabbar.vue' import tabBarItem from '@/page/tabbar/TabBarItem.vue'; export default { name: 'App', components: { tabBar, tabBarItem } } </script> <style> @import url("~@/common/style/base.css"); </style>
4.路由跳转
-
安装路由:npm install vue-router
-
使用
-
创建router
-
index.js
//配置路由相关信息 import Vue from 'vue' import VueRouter from 'vue-router'; // 通过vue.use(路由插件),安装插件 Vue.use(VueRouter) // 路由懒加载 const home = () => import("@/page/home/index.vue") const category = () => import("@/page/category/index.vue") const cart = () => import("@/page/cart/index.vue") const my = () => import("@/page/my/index.vue") // 定义路由 let routes = [{ path: "", redireact: '/home' }, { path: "/home", name: "首页", component: home }, { path: "/category", name: "分类", component: category, }, { path: "/cart", name: "购物车", component: cart }, { path: "/my", component: my, name: "我的" }, ] // 创建router实例 let router = new VueRouter({ // 配置路由和组件之间的应用关系 mode: "history", //abstract || history || hash= routes }) // 导出router实例 export default router
-
-
在main引入,并重新启动项目
import router from './router/index.js';
-
app.js
<template> <div id="app"> <router-view></router-view> <mainTab></mainTab> </div> </template> <script> import mainTab from '@/page/mainTable/index.vue' export default { name: 'App', components: { mainTab } } </script> <style> @import url("~@/common/style/base.css"); </style>
-
tabbarItem.vue发生改变
<template> <router-link class="tab-bar-item" :tag="tags" :to="path"> <slot name="item-icon"></slot> <slot name="item-text"></slot> </router-link> </template> <script> export default { props: { path: { type: String, default: "", }, tags:{ type:String, default:"div" } }, } </script> <style> .tab-bar-item { flex: 1; text-align: center; height: 49px; } .tab-bar-item img { width: 24px; height: 24px; } .tab-bar-item { flex: 1; text-align: center; height: 49px; font-size: 14px; } .tab-bar-item img { width: 24px; height: 24px; margin-top: 3px; /*去掉图片下面多出来的3像素*/ vertical-align: middle; } </style>
-
5.点击Item跳转对应路由,并动态决定isActive
tabbarItem.vue
<template> <router-link class="tab-bar-item" :tag="tags" :to="path"> <div v-if="isActive"> <slot name="item-icon-active"></slot> </div> <div v-if='!isActive'> <slot name="item-icon"></slot> </div> <slot name="item-text"></slot> </router-link> </template> <script> export default { props: { path: { type: String, default: "", }, tags: { type: String, default: "div" }, }, computed: { isActive() { return this.$route.path.indexOf(this.path) !== -1; }, }, } </script> <style> .tab-bar-item { flex: 1; text-align: center; height: 49px; } .tab-bar-item img { width: 24px; height: 24px; } .tab-bar-item { flex: 1; text-align: center; height: 49px; font-size: 14px; } .tab-bar-item img { width: 24px; height: 24px; margin-top: 3px; /*去掉图片下面多出来的3像素*/ vertical-align: middle; } </style>
mainTable.vue
<template> <div id="app"> <tabBar> <tabBarItem path="/home" > <img slot="item-icon-active" src="~@/common/img/tabbar/home_active.svg" alt="" /> <img slot="item-icon" src="~@/common/img/tabbar/home.svg" alt="" /> <div slot="item-text">首页</div> </tabBarItem> <tabBarItem path="/category" > <img slot="item-icon-active" src="~@/common/img/tabbar/category_active.svg" alt="" /> <img slot="item-icon" src="~@/common/img/tabbar/category.svg" alt="" /> <div slot="item-text">分类</div> </tabBarItem> <tabBarItem path="/cart"> <img slot="item-icon-active" src="~@/common/img/tabbar/shopcart_active.svg" alt="" /> <img slot="item-icon" src="~@/common/img/tabbar/shopcart.svg" alt="" /> <div slot="item-text">购物车</div> </tabBarItem> <tabBarItem path="/my"> <img slot="item-icon-active" src="~@/common/img/tabbar/profile_active.svg" alt="" /> <img slot="item-icon" src="~@/common/img/tabbar/profile.svg" alt="" /> <div slot="item-text">我的</div> </tabBarItem> </tabBar> </div> </template> <script> import tabBar from '@/page/tabbar/tabbar.vue' import tabBarItem from '@/page/tabbar/TabBarItem.vue'; export default { components: { tabBar, tabBarItem } } </script> <style> </style>
5.动态计算active样式并且不同的分类显示不同颜色
<template> <router-link class="tab-bar-item" :tag="tags" :to="path"> <div v-if="isActive"> <slot name="item-icon-active"></slot> </div> <div v-if='!isActive'> <slot name="item-icon"></slot> </div> <div :style="activeStyle"> <slot name="item-text"></slot> </div> </router-link> </template> <script> export default { props: { path: { type: String, default: "", }, tags: { type: String, default: "div" }, activeColor:{ type:String, default:'' } }, computed: { isActive() { return this.$route.path.indexOf(this.path) !== -1; }, activeStyle(){ return this.isActive? {'color': this.activeColor} : {} } }, } </script> <style> .tab-bar-item { flex: 1; text-align: center; height: 49px; } .tab-bar-item img { width: 24px; height: 24px; } .tab-bar-item { flex: 1; text-align: center; height: 49px; font-size: 14px; } .tab-bar-item img { width: 24px; height: 24px; margin-top: 3px; /*去掉图片下面多出来的3像素*/ vertical-align: middle; } </style>
mainTable.vue
<tabBarItem path="/home" activeColor="red"> <img slot="item-icon" src="~@/assets/img/tabbar/home.svg" alt="" /> <img slot="item-icon-active" src="~@/assets/img/tabbar/home_active.svg" alt="" /> <div slot="item-text">首页</div> </tabBarItem> <tabBarItem path="/category" activeColor="green"> <img slot="item-icon" src="~@/assets/img/tabbar/category.svg" alt="" /> <img slot="item-icon-active" src="~@/assets/img/tabbar/category_active.svg" alt="" /> <div slot="item-text">分类</div> </tabBarItem> <tabBarItem path="/cart" activeColor="yellow"> <img slot="item-icon" src="~@/assets/img/tabbar/shopcart.svg" alt="" /> <img slot="item-icon-active" src="~@/assets/img/tabbar/shopcart_active.svg" alt="" /> <div slot="item-text">购物车</div> </tabBarItem> <tabBarItem path="/my" activeColor="blue"> <img slot="item-icon" src="~@/assets/img/tabbar/profile.svg" alt="" /> <img slot="item-icon-active" src="~@/assets/img/tabbar/profile_active.svg" alt="" /> <div slot="item-text">我的</div> </tabBarItem> </tabbar>
6.动态添加数据并进行切换
<template> <div id="app"> <tabBar> <tabBarItem v-for="(item,index) in tabList" :key="index" :path="item.path" :activeColor='item.activeColor'> <img slot="item-icon-active" :src="item.itemIconActive" alt="" /> <img slot="item-icon" :src="item.itemIcon" alt="" /> <div slot="item-text">{{item.label}}</div> </tabBarItem> </tabBar> </div> </template> <script> import tabBar from '@/page/tabbar/tabbar.vue' import tabBarItem from '@/page/tabbar/TabBarItem.vue'; export default { components: { tabBar, tabBarItem }, data() { return { tabList: [{ path: "/home", activeColor: "red", itemIcon: require("@/common/img/tabbar/home.svg"), itemIconActive: require("@/common/img/tabbar/home_active.svg"), label: "首页" }, { path: "/category", activeColor: "yellow", itemIcon: require("@/common/img/tabbar/category.svg"), itemIconActive: require("@/common/img/tabbar/category_active.svg"), label: "分类" }, { path: "/cart", activeColor: "blue", itemIcon: require("@/common/img/tabbar/shopcart.svg"), itemIconActive: require("@/common/img/tabbar/shopcart_active.svg"), label: "购物车" }, { path: "/my", activeColor: "green", itemIcon: require("@/common/img/tabbar/profile.svg"), itemIconActive: require("@/common/img/tabbar/profile_active.svg"), label: "我的" }, ] } } } </script> <style> </style>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3V24mBB3-1647787006890)(E:\资料存档\资料笔记\总结项目\img\image-20220320223346570.png)]
activeColor: "yellow", itemIcon: require("@/common/img/tabbar/category.svg"), itemIconActive: require("@/common/img/tabbar/category_active.svg"), label: "分类" }, { path: "/cart", activeColor: "blue", itemIcon: require("@/common/img/tabbar/shopcart.svg"), itemIconActive: require("@/common/img/tabbar/shopcart_active.svg"), label: "购物车" }, { path: "/my", activeColor: "green", itemIcon: require("@/common/img/tabbar/profile.svg"), itemIconActive: require("@/common/img/tabbar/profile_active.svg"), label: "我的" }, ] } } }
![在这里插入图片描述](https://www.www.zyiz.net/i/ll/?i=7574d5cdf6984a3c8fad2180f4d8d9ef.png#pic_center) ![在这里插入图片描述](https://www.www.zyiz.net/i/ll/?i=b46f5bb2ce8e4df88a3981216f77adc6.png?,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56iL5bqP5r2H5r2H,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
这篇关于tabbar的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-13TiDB + ES:转转业财系统亿级数据存储优化实践
- 2024-05-09“2024鸿蒙零基础快速实战-仿抖音App开发(ArkTS版)”实战课程已上线
- 2024-05-09聊聊如何通过arthas-tunnel-server来远程管理所有需要arthas监控的应用
- 2024-05-09log4j2这么配就对了
- 2024-05-09nginx修改Content-Type
- 2024-05-09Redis多数据源,看这篇就够了
- 2024-05-09Google Chrome驱动程序 124.0.6367.62(正式版本)去哪下载?
- 2024-05-09有没有大佬知道这种数据应该怎么抓取呀?
- 2024-05-09这种运行结果里的10.100000001,怎么能最快改成10.1?
- 2024-05-09企业src漏洞挖掘-有意思的命令执行