Vue 如何实现一个底部导航栏组件

参考网址: 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>
posted @ 2021-08-21 20:25  MaxBruce  阅读(422)  评论(0编辑  收藏  举报