参考网址: https://www.jianshu.com/p/088936b7b1bd/
Vue 如何实现一个底部导航栏组件
可以看到父组件是知道我点击了底部TabBar的哪个item的。
实现
实现template 和style
我用的布局工具是bootstrap,图标是阿里巴巴的iconfont
<template>
<div id="TabBar" class="tab-bar row">
<div class="col-xs-4 tab-bar-item">
<div class="row">
<i class="iconfont icon-daohangshouye"></i>
</div>
<div class="row">
<span>首页</span>
</div>
</div>
<div class="col-xs-4 tab-bar-item">
<div class="row">
<i class="iconfont icon-shangjia"></i>
</div>
<div class="row">
<span>商户</span>
</div>
</div>
<div class="col-xs-4 tab-bar-item">
<div class="row">
<i class="iconfont icon-huiyuan"></i>
</div>
<div class="row">
<span>我的</span>
</div>
</div>
</div>
</template>
<style scoped>
.tab-bar {
background-color: white;
height: 54px;
border: 0 solid rgb(210, 210, 210);
border-top-width: 1px;
position: fixed;
margin: auto;
bottom: 0;
width: 100%;
}
.tab-bar-item {
height: 54px;
}
i {
font-size: 25px;
}
</style>
实现点击事件
在每个tab-bar-item的div上添加@click绑定点击事件并且传递当前是哪个item,第一个item就可以传一个tag=0的参数。实现如下:
<div class="col-xs-4 tab-bar-item" @click="didClickedItem(0)">
<div class="row">
<i class="iconfont icon-daohangshouye"></i>
</div>
<div class="row">
<span>首页</span>
</div>
</div>
didClickedItem: function (tag) {
if (tag === 0) {
} else if (tag === 1) {
} else if (tag === 2) {
}
}
点击完肯定需要让那个item进入选中的状态,也就是变亮,可以通过v-bind:class去做。data存一个数组放bool变量,因为第一个item肯定默认点亮,所以数组第一个元素为true。每次点击别的item时先把数组元素全部置位false,然后把选中的item所对应的数组元素改为true就可以实现选中效果。实现如下:
data: function () {
return {
actives: [true, false, false]
}
}
<div class="col-xs-4 tab-bar-item" @click="didClickedItem(0)" v-bind:class="{active: actives[0]}">
<div class="row">
<i class="iconfont icon-daohangshouye"></i>
</div>
<div class="row">
<span>首页</span>
</div>
</div>
didClickedItem: function (tag) {
this.actives = this.actives.map(function () {
return false;
});
this.actives[tag] = true;
}
.active {
color: #1E90FF;
}
对外暴露方法
选中一个item肯定需要让父组件知道你选了什么,所以肯定要对外暴露方法,这个方法在didClickedItem这个方法最后一行加一行代码即可
# TabBar组件里
this.$emit(‘select-item‘, tag);
# 父组件使用方法
<template>
<div id="app">
<div style="font-size: 20px">{{item}}</div>
<TabBar @select-item="onClickTabBarItem"/>
</div>
</template>
<script>
import TabBar from ‘./components/TabBar‘
export default {
name: ‘app‘,
data: function () {
return {
item: 0
}
},
components: {
TabBar
},
methods: {
onClickTabBarItem: function (tag) {
this.item = tag;
}
}
}
</script>
完整代码
<template>
<div id="TabBar" class="tab-bar row">
<div class="col-xs-4 tab-bar-item" @click="didClickedItem(0)" v-bind:class="{active: actives[0]}">
<div class="row">
<i class="iconfont icon-daohangshouye"></i>
</div>
<div class="row">
<span>首页</span>
</div>
</div>
<div class="col-xs-4 tab-bar-item" @click="didClickedItem(1)" v-bind:class="{active: actives[1]}">
<div class="row">
<i class="iconfont icon-shangjia"></i>
</div>
<div class="row">
<span>商户</span>
</div>
</div>
<div class="col-xs-4 tab-bar-item" @click="didClickedItem(2)" v-bind:class="{active: actives[2]}">
<div class="row">
<i class="iconfont icon-huiyuan"></i>
</div>
<div class="row">
<span>我的</span>
</div>
</div>
</div>
</template>
<script>
export default {
name: "TabBar",
props: {
},
data: function () {
return {
actives: [true, false, false]
}
},
methods: {
didClickedItem: function (tag) {
if (tag === 0) {
this.actives = this.actives.map(function () {
return false;
});
this.actives[0] = true;
} else if (tag === 1) {
this.actives = this.actives.map(function () {
return false;
});
this.actives[1] = true;
} else if (tag === 2) {
this.actives = this.actives.map(function () {
return false;
});
this.actives[2] = true;
}
this.$emit(‘select-item‘, tag);
}
}
}
</script>
<style scoped>
.tab-bar {
background-color: white;
height: 54px;
border: 0 solid rgb(210, 210, 210);
border-top-width: 1px;
position: fixed;
margin: auto;
bottom: 0;
width: 100%;
}
.tab-bar-item {
height: 54px;
}
.active {
color: #1E90FF;
}
i {
font-size: 25px;
}
</style>