start_time: 2024-04-30 22:58:45 +0800

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

96
QYiZHong
IP属地: 河北
0.1 2018.11.04 12:00 字数 299

演示效果

演示效果

可以看到父组件是知道我点击了底部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>
最后编辑于 :2018-11-04 13:07:25
©著作权归作者所有,转载或内容合作请联系作者
序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
783c64db 45e5 48d7 82e4 95736f50533e 沈念sama 阅读 160026 评论 4 赞 364
序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
783c64db 45e5 48d7 82e4 95736f50533e 沈念sama 阅读 67655 评论 1 赞 296
文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
8 开封第一讲书人 阅读 109726 评论 0 赞 244
文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
8 开封第一讲书人 阅读 44204 评论 0 赞 213
正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
388e473c fe2f 40e0 9301 e357ae8f1b41 茶点故事 阅读 52558 评论 3 赞 287
文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
8 开封第一讲书人 阅读 40731 评论 1 赞 222
那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
783c64db 45e5 48d7 82e4 95736f50533e 沈念sama 阅读 31944 评论 2 赞 314
文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
8 开封第一讲书人 阅读 30698 评论 0 赞 203
序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
783c64db 45e5 48d7 82e4 95736f50533e 沈念sama 阅读 34438 评论 1 赞 246
正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
388e473c fe2f 40e0 9301 e357ae8f1b41 茶点故事 阅读 30633 评论 2 赞 247
正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
388e473c fe2f 40e0 9301 e357ae8f1b41 茶点故事 阅读 32125 评论 1 赞 260
序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
783c64db 45e5 48d7 82e4 95736f50533e 沈念sama 阅读 28444 评论 3 赞 255
正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
388e473c fe2f 40e0 9301 e357ae8f1b41 茶点故事 阅读 33137 评论 3 赞 238
文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
8 开封第一讲书人 阅读 26103 评论 0 赞 8
文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
8 开封第一讲书人 阅读 26888 评论 0 赞 197
我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
783c64db 45e5 48d7 82e4 95736f50533e 沈念sama 阅读 35772 评论 2 赞 276
正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
388e473c fe2f 40e0 9301 e357ae8f1b41 茶点故事 阅读 35669 评论 2 赞 271
end_time: 2024-04-30 22:58:45 +0800 Completed in 144.731167ms