-
以下是项目框架 , 我们先将底部的导航抽取成一个 TaBra 组件 , 再将 其中的 4 个部分再抽取成一个 组件 Tabra-Item

-
1. 创建 TaBra.vue
-
创建TaBra.vue 后 , 在其模板中准备一个插槽 , 用于抽取 Tabra-Item
<template> <div id="tab-bar"> <slot>slot> div> template> <script> export default { name: "TabBar" } script> <style scoped> #tab-bar{ display: flex; background-color: #f6f6f6; position: fixed; left: 0px; right: 0px; bottom: 0px; box-shadow: 0px -1px 1px rgba(144, 147, 145, 0.2); } style>
-
2. 抽取Tabra-Item
在组件中提供3个插槽 , 一个是未获取焦点的图片 , 一个是获取焦点后的图片 , 还有一个是文本
<template> <div class="tab-bar-item"> <slot name="item-icon">slot> <slot name="item-icon-active">slot> <slot name="item-text">slot> div> template> <script> export default { name: "TabBarItem", } script> <style scoped> .tab-bar-item{ flex: 1; text-align: center; height: 49px; } .tab-bar-item img{ height: 24px; width: 24px; } .activeText{ color: red; } style>
-
3. 在Vue.app中引用
使用tab-bar-item组件 , 通过父传子将 path 和 activetext 传递到子组件 , 因为此处是固定的 , 不是一个变量 , 所以可以不动态绑定
path: 跳转的路径
activeText: Tabra-Item 选中后的 text 颜色
在
传递2个图片 , 一个是选中的 , 一个是未选中的 , 可以通过具名插槽在 Tabra-Item 组件中通过 v-if
来判断显示哪一个
<template> <div id="app"> <router-view>router-view> <tab-bar> <tab-bar-item class="tab-bar-item" path="/home" activeText="red"> <img class="" slot="item-icon" src="./assets/img/tabbar/home.svg"/> <img class="" slot="item-icon-active" src="./assets/img/tabbar/home_active.svg"/> <div slot="item-text">首页div> tab-bar-item> <tab-bar-item class="tab-bar-item" path="/category" activeText="red"> <img slot="item-icon" src="./assets/img/tabbar/category.svg"/> <img slot="item-icon-active" src="./assets/img/tabbar/category_active.svg"/> <div slot="item-text">分类div> tab-bar-item> <tab-bar-item class="tab-bar-item" path="/cart" activeText="red"> <img slot="item-icon" src="./assets/img/tabbar/cart.svg"/> <img slot="item-icon-active" src="./assets/img/tabbar/cart_active.svg"/> <div slot="item-text">购物车div> tab-bar-item> <tab-bar-item class="tab-bar-item" path="/profile" activeText="red"> <img slot="item-icon" src="./assets/img/tabbar/profile.svg"/> <img slot="item-icon-active" src="./assets/img/tabbar/profile_active.svg"/> <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>
-
4. 我们创建4个对应 Tabra-Item 的组件
创建4个组件 , 分别是home category cart profile , 通过路由进行跳转 , 既然需要跳转 , 那么就需要监听事件 , 我们在 Tabra-Item 中进行监听
我们通过 props
属性获取第3步所传入的 path
属性, 通过调用 this.$router.push(this.path);
进行跳转
我们通过 isActive
函数来判断当前 Tabra-Item 是否处于选中状态 , 如果处于选中状态 , 我们就显示选中的图片也就是显示具名插槽 item-icon-active
通过 setActiveText
函数设置 文本颜色 我们在第3步时传入了一个文本颜色 activeText
我们可以用 :style="setActiveText"
动态绑定 style
的方式从 setActiveText
函数获取到 css
样式
<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="setActiveText"> <slot name="item-text">slot> div> div> template> <script> export default { name: "TabBarItem", props: { path : String, activeText:{ type: String, default(){ return "black" } } }, data(){ return { active: true } }, computed: { isActive() { return this.$route.path.indexOf(this.path) != -1 }, setActiveText() { return this.isActive ? {color: this.activeText} : {color: "black"} } }, methods: { ItemClick() { this.$router.push(this.path); } } } script> <style scoped> .tab-bar-item{ flex: 1; text-align: center; height: 49px; } .tab-bar-item img{ height: 24px; width: 24px; } .activeText{ color: red; } style>