Vue.js 学习笔记阶段案例:TabBar

目录

阶段案例:TabBar


阶段案例:TabBar

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

效果图:

实现思路

首先自定义 TabBar 组件。在 APP 中使用,让 TabBar 位于底部,并且设置相关的样式。TabBar 中显示的内容由外界决定。定义插槽,flex 布局平分 TabBar。

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

代码实现

先创建名为 tabbar 的项目(选择自定义,添加路由)。

vue create tabbar

把准备好的静态资源图标和基本样式放在项目里。

 |- /assets
+   |- /css
		| - base.css // 基本样式
+   |- /font // 这里使用iconfont字体图标
		| - iconfont.css
		| - iconfont.ttf

src/assets/css/base.css

body {
	padding: 0;
  margin: 0;
}

/* 活动路由 class */
.active {
	color: #aa0000;
}
/* 图标字体大小 */
.iconfont {
	font-size: 20px;
}

创建四个视图组件。

src/views/Home.vue

<template>
  <div class="home">
    <h1>This is an home page</h1>
  </div>
</template>

<script>

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

<style>
	
</style>

src/views/Category.vue

<template>
	<div class="category">
		<h1>This is an category page</h1>
	</div>
</template>

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

<style>
	
</style>

src/views/ShoppingCart.vue

<template>
	<div class="shopping-cart">
		<h1>This is an shopping cart page</h1>
	</div>
</template>

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

<style>
	
</style>

src/views/Mine.vue

<template>
  <div class="mine">
    <h1>This is an mine page</h1>
  </div>
</template>

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

<style>
	
</style>

配置路由。

src/router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

const routes = [
	{
		path: '/',
		redirect: '/home'
	},
  {
    path: '/home',
    name: 'Home',
    component: Home
  },
  {
    path: '/category',
    name: 'Category',
    component: () => import('../views/Category.vue')
  },
  {
    path: '/shoppingCart',
    name: 'ShoppingCart',
    component: () => import('../views/ShoppingCart.vue')
  }, 
	{
    path: '/mine',
    name: 'Mine',
    component: () => import('../views/Mine.vue')
  }
	
]

const router = new VueRouter({
  routes,
	// 配置活动路由 class
	linkActiveClass: 'active'
})

export default router

创建 TabBar 和 TabBarItem 组件。

src/components/tabbar/TabBarItem .vue

<template>
	<div class="tab-bar-item">
		<!-- 路由组件,绑定当前组件的 path 属性,编译成 div 标签 -->
		<router-link :to="path" tag="div">
			<!-- 非活动路由状态下,图标命名插槽 -->
			<slot v-if="!isActive" name="item-icon"></slot>
			<!-- 活动路由状态下,图标命名插槽 -->
			<slot v-else name="item-icon-active"></slot>
			<!-- 文字命名插槽 -->
			<slot name="item-title"></slot>
		</router-link>
	</div>
</template>

<script>
	export default {
		name: 'TabBarItem',		
		props: {
			path: {
				type: String,
				required: true
			}
		},
		computed: {
			isActive() {
				// 计算属性,当前路由是否处于活动的状态,显示不同的图标
				return this.$route.path.indexOf(this.path) !== -1
			}
		}
	}
</script>

<style scoped>	
	/* 本身样式 */
	.tab-bar-item {
		flex: 1;
		text-align: center;
		height: 40px;
		font-size: 12px;
		margin-top: 10px;
	}
</style>

src/components/tabbar/TabBar .vue

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

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

<style scoped>
	/* 本身样式 */
	#tab-bar {
		background-color: #F1F1F1;
		box-shadow: 0 -1px 1px rgba(100,100,100,.2);
		font-size: 14px;
		
		/* 使用 flex 进行布局 */
		display: flex;

		/* 定位相关 */
		position: fixed;
		left: 0;
		right: 0;
		bottom: 0;
	}
</style>

修改 App.vue

<template>
  <div id="app">
		<router-view></router-view>
		<tab-bar>
			<!-- 首页 -->
			<tab-bar-item path="/home">
				<template #item-icon>
					<div class="iconfont icon-shouye-xianxing"></div>
				</template>
				<template #item-icon-active>
					<div class="iconfont icon-shouye-mianxing"></div>
				</template>
				<template #item-title><div>首页</div></template>				
			</tab-bar-item>
			<!-- 分类 -->
			<tab-bar-item path="/category">
				<template #item-icon>
					<div class="iconfont icon-fenlei-xianxing"></div>
				</template>
				<template #item-icon-active>
					<div class="iconfont icon-fenlei-mianxing"></div>
				</template>
				<template #item-title><div>分类</div></template>				
			</tab-bar-item>
			<!-- 购物车 -->
			<tab-bar-item path="/shoppingCart">
				<template #item-icon>
					<div class="iconfont icon-gouwuche-xianxing"></div>
				</template>
				<template #item-icon-active>
					<div class="iconfont icon-gouwuche-mianxing"></div>
				</template>
				<template #item-title><div>购物车</div></template>				
			</tab-bar-item>
			<!-- 我的 -->
			<tab-bar-item path="/mine">
				<template #item-icon>
					<div class="iconfont icon-wode-xianxing-1"></div>
				</template>
				<template #item-icon-active>
					<div class="iconfont icon-wode-mianxing-1"></div>
				</template>
				<template #item-title><div>我的</div></template>				
			</tab-bar-item>			
		</tab-bar>
	<!-- 
    <div id="tab-bar">
			<div class="tab-bar-item active">
				<div class="iconfont icon-shouye-mianxing"></div>
				<div>首页</div>
			</div>
			<div class="tab-bar-item">
				<div class="iconfont icon-fenlei-xianxing"></div>
				<div>分类</div>
			</div>
			<div class="tab-bar-item">
				<div class="iconfont icon-gouwuche-xianxing"></div>
				<div>购物车</div>
			</div>
			<div class="tab-bar-item">
				<div class="iconfont icon-wode-xianxing-1"></div>
				<div>我的</div>
			</div>
		</div>-->
  </div>
</template>
<script>
	// 导入 TabBar 和 TabBarItem 俩个组件
	import TabBar from './components/tabbar/TabBar.vue'
	import TabBarItem from './components/tabbar/TabBarItem.vue'
	export default {
		name: "App",
		components: {
			TabBar,
			TabBarItem
		}
	}
</script>
<style>
	/* 导入基本样式 */
	@import url("assets/css/base.css");
	/* 导入iconfont字体图标 */
	@import url("assets/font/iconfont.css");
</style>

这里为大家提供该案例中 iconfont 字体图标在线链接:

     @import url("//at.alicdn.com/t/font_2543261_qfljvc23ga.css");
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

stary1993

你的鼓励是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值