1. 在下方有一个单独的TabBar组件
- 自定义TabBar组件,在APP中使用
- 让TabBar出于底部,并且设置相关的样式
2.TabBar中显示的内容由外界决定
- 定义插槽
- flex布局平分TabBar
3.自定义TabBarItem,可以传入 图片和文字
- 定义TabBarItem,并且定义两个插槽:图片、文字。
- 给两个插槽外层包装div,用于设置样式。
- 填充插槽,实现底部TabBar的效果
4.传入 高亮图片
定义另外一个插槽,插入active-icon的数据
定义一个变量isActive,通过v-show来决定是否显示对应的icon
5.TabBarItem绑定路由数据
安装路由:npm install vue-router —save
完成router/index.js的内容,以及创建对应的组件
main.js中注册router
APP中加入<router-view>组件
6.点击item跳转到对应路由,并且动态决定isActive
监听item的点击,通过this.$router.replace()替换路由路径
通过this.$route.path.indexOf(this.link) !== -1来判断是否是active
7.动态计算active样式
封装新的计算属性:this.isActive ? {'color': 'red'} : {}
tabbar
<template>
<div id="tab-bar">
<slot></slot>
</div>
</template>
<script>
export default {
data () {
return {
}
},
components: {
}
}
</script>
<style>
#tab-bar{
display: flex;
background: #f6f6f6;
position: fixed;
padding: 0px;
margin: 0px;
left: 0;
right: 0;
bottom: 0;
}
</style>
tabbaritem
<template>
<div class="tab-bar-item" @click="clickTabBarItem()">
<div v-if="!active">
<slot name="item-icon" />
</div>
<div v-if="active">
<slot name="item-icon-active" />
</div>
<div :style="textStyle">
<slot name="item-text" />
</div>
</div>
</template>
<script>
export default {
props: {
path: String,
color: {
type: String,
default: "red"
}
},
data() {
return {};
},
methods: {
clickTabBarItem() {
this.active = true;
this.$router.replace(this.path);
}
},
computed: {
active: {
get: function() {
//判断当前活跃路由路径里有没有本组件名
return !(this.$route.path.indexOf(this.path) == -1);
},
// setter
set: function(newValue) {}
},
textStyle: {
get: function() {
return this.active ? { color: this.color } : {};
},
// setter
set: function(newValue) {}
}
},
components: {}
};
</script>
<style>
.tab-bar-item {
flex: 1;
text-align: center;
height: 49px;
box-shadow: 0 -3px 1px rgba(100, 100, 100, 0.2);
font-size: 14px;
}
.tab-bar-item img {
height: 24px;
width: 24px;
margin-top: 3px;
vertical-align: 0px;
}
</style>
router里的index.js
import vue from "vue"
import VueRouter from "vue-router"
vue.use(VueRouter)
export default new VueRouter({
mode: 'history',
routes: [
{
path: '/',
redirect:'/home'
}, {
path: '/home',
component: () => import('../pages/home/Home')
}, {
path: '/profile',
component: () => import('../pages/profile/Profile')
}, {
path: '/shopcar',
component: () => import('../pages/shopcar/Shopcar')
}, {
path: '/catagory',
component: () => import('../pages/catagory/Catagory')
}
]
})
毫无新意的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)
})
汇总的app.vue
<template>
<div id="app">
<router-view/>
<tab-bar>
<tab-bar-item path="/home" color='red'>
<img src="./assets/img/tabbar/home.svg" slot="item-icon" />
<img src="./assets/img/tabbar/home_active.svg" slot="item-icon-active" />
<div slot="item-text">首页</div>
</tab-bar-item>
<tab-bar-item path="/catagory" color='yellow'>
<img src="./assets/img/tabbar/category.svg" slot="item-icon" />
<img src="./assets/img/tabbar/category_active.svg" slot="item-icon-active" />
<div slot="item-text">分类</div>
</tab-bar-item>
<tab-bar-item path="/shopcar" color='blue'>
<img src="./assets/img/tabbar/shopcart.svg" slot="item-icon" />
<img src="./assets/img/tabbar/shopcart_active.svg" slot="item-icon-active" />
<div slot="item-text">购物车</div>
</tab-bar-item>
<tab-bar-item path="/profile" color='black'>
<img src="./assets/img/tabbar/profile.svg" slot="item-icon" />
<img src="./assets/img/tabbar/profile_active.svg" slot="item-icon-active" />
<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>
一个小demo的学习,似乎让我稍微理解了一下组件化开发过程中的封装和复用思想. 钩子函数和路由里的几个函数在组件间进行交互时候似乎显得尤其重要.
害,咱的VsCode咋感觉代码提示这么差劲呢?我TM都敲完了你都没识别我用的函数...下了vuehelper也不顶用