ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

tabbar

2022-03-20 23:02:27  阅读:183  来源: 互联网

标签:vue bar tabbar img item tab


TabBar 的实现功能

在这里插入图片描述

TabBar实现思路

  1. 如果在下方有一个单独的Tabbar组件,你如何封装
    1. 自定义TabBar组件,在APP中使用
    2. 让TabBar出于底部,并且设置相关的样式
  2. TabBar中显示的内容有外界决定
    1. 定义插槽
    2. flex布局平分TabBar
  3. 自定义TabBarItem,可以传入图片和文字
    1. 定义TabBarItem,并且定义两个插槽:图片、文字。
    2. 给两个插槽外层包装div,用于设置样式。
    3. 填充插槽,实现底部TabBar的效果
  4. 传入高亮图片
    1. 定义另外一个插槽,插入active-icon的数据
    2. 定义一个变量isActive,通过v-show来决定是否显示对应的icon
  5. TabBarItem绑定路由数据
    1. 安装路由:npm install vue-router —save
    2. 完成router/index.js的内容,以及创建对应的组件
    3. main.js中注册router
    4. APP中加入<router-view>组件
  6. 点击Item跳转对应路由,并动态决定isActive
    1. 监听item的点击,通过this.$router.replace()替换路由路径
    2. 通过this.$route.path.indexOf(this.link) !== -1来判断是否是active
  7. 动态计算active样式并且不同的分类显示不同的颜色
    1. 封装新的计算属性:this.isActive ? {'color': 'red'} : {}
  8. 动态添加数据并进行切换
    1. 将数据定义到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.路由跳转

  1. 安装路由:npm install vue-router

  2. 使用

    1. 创建router

      1. 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
        
    2. 在main引入,并重新启动项目

      import router from './router/index.js';
      
    3. 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>
      
      
    4. 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.icode9.com/i/ll/?i=7574d5cdf6984a3c8fad2180f4d8d9ef.png#pic_center)
![在这里插入图片描述](https://www.icode9.com/i/ll/?i=b46f5bb2ce8e4df88a3981216f77adc6.png?,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56iL5bqP5r2H5r2H,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)

标签:vue,bar,tabbar,img,item,tab
来源: https://blog.csdn.net/fxxx_/article/details/123623630

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有