TabBar实现思路
1.如果在下方有一个单独的TabBar组件,你如何封装?
- 自定义TabBar组件,然后在app上使用。
- 让tabBar处于底部,并且设置相关的样式。
2.TabBar中显示的内容由外界决定
- 定义插槽
- flex布局平分tabBar
3.自定义TabBarItem,可以传入照片和文字
- 定义TabBarItem,并且定义两个插槽:图片和文字;
- 给两个插槽外层包装div,用于设置样式;
- 填充插槽,实现底部TabBar的效果。
TabBar实现代码
首先创建一个vue-cli2项目
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ydLe0hPD-1608295702978)(D:\1吴婧怡\Typora\前端\Vue\image-20201213121811886.png)]
App.vue
<template>
<div id="app">
<router-view></router-view>
<tab-bar>
<tab-bar-item path="/Home">
<img slot="item-icon" src="./assets/img/tabbar/1.png" alt="" />
<img slot="item-icon-active" src="./assets/img/tabbar/5.png" alt="" />
<div slot="item-text">首页</div>
</tab-bar-item>
<tab-bar-item path="/Category" activeClolor="purple">
<img slot="item-icon" src="./assets/img/tabbar/2.png" alt="" />
<img slot="item-icon-active" src="./assets/img/tabbar/6.png" alt="" />
<div slot="item-text">分类</div>
</tab-bar-item>
<tab-bar-item path="/Shopcar">
<img slot="item-icon" src="./assets/img/tabbar/3.png" alt="" />
<img slot="item-icon-active" src="./assets/img/tabbar/7.png" alt="" />
<div slot="item-text">购物车</div>
</tab-bar-item>
<tab-bar-item path="/Profile">
<img slot="item-icon" src="./assets/img/tabbar/4.png" alt="" />
<img slot="item-icon-active" src="./assets/img/tabbar/8.png" alt="" />
<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>
@import "./assets/css/base.css";
</style>
TabBar.vue
<template>
<div id="tab-bar">
<slot></slot>
</div>
</template>
<script>
export default {
name: "TabBar",
};
</script>
<style>
#tab-bar {
display: flex;
width: 100%;
background: #f6f6f6;
position: fixed;
left: 0;
right: 0;
bottom: 0;
box-shadow: 0px 0px 5px rgba(169, 169, 169, 0.381);
/* 阴影 */
}
</style>
TabBarItem.vue
<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="activeStyle">
<slot name="item-text"></slot>
</div>
</div>
</template>
<script>
export default {
name: "TabBarItem",
props: {
path: String,
activeColor:{
type:String,
default:'brown'
}
},
data() {
return {
// isActive: true,
};
},
computed:{
isActive(){
return this.$route.path.indexOf(this.path)!==-1;
},
activeStyle(){
return this.isActive?{color:this.activeColor}:{}
}
},
methods: {
changeIsActive() {
this.isActive = !this.isActive;
},
itemClick() {
this.$router.replace(this.path);
},
},
};
</script>
<style scoped>
.tab-bar-item {
flex: 1;
text-align: center;
height: 49px;
font-size: 14px;
}
.tab-bar-item img {
width: 24px;
height: 24px;
margin-top: 3px;
vertical-align: middle;
margin-bottom: 2px;
}
</style>
Home/Category/Shopcar/Profile.vue
<template>
<h2>Home/Category/Shopcar/Profile</h2>
</template>
<script>
export default {
name:"Home/Category/Shopcar/Profile"
}
</script>
<style>
</style>
index.js
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const Home=()=>import('../views/home/Home')
const Category=()=>import('../views/category/Category')
const Profile=()=>import('../views/profile/Profile')
const Shopcar=()=>import('../views/shopcar/Shopcar')
const routes= [
{
path: '/Home',
component: Home
},
{
path: '/Category',
component: Category
},
{
path: '/Profile',
component: Profile
},
{
path: '/Shopcar',
component: Shopcar
}
]
export default new Router({
routes,
mode:'history'
})
main.js
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)
})
// require('./assets/css/base.css')