Nuxt/Vue仿咸鱼Tabbar凸起效果|vue自定义导航栏

引言

在手机端项目开发时,很多场景下标签栏TabBar和导航栏NavBar功能必不可少。由于Nuxt项目中需要用到类似咸鱼底部凸起导航效果,只能自己动手造一个自定义导航组件。

image.png
如上图:在项目中实例效果

ok,下面就详细讲解下实现方法。

首先,需要在components目录下新建 headerBar.vuetabBar.vue 页面。

image.png

紧接着,在 plugins 目录下新建 componentsInstall.js 文件并引入即可。

image.png

Nuxt自定义导航条headerBar

<template>
    <div class="header-bar" :class="{'fixed': fixed, 'transparent fixed': transparent}">
        <div class="header-bar__wrap flexbox flex-alignc" :style="{'background': bgcolor, 'color': color, 'z-index': zIndex}">
            <!-- >>返回 -->
            <div class="action hdbar-action__left isback" v-if="back && back!='false'" @click="$router.go(-1)">
                <slot name="backIco" /><slot name="backText" />
            </div>
 
            <!-- >>标题 -->
            <div class="hdbar-title" :class="{'center': center}">
                <slot name="title" />
            </div>
 
            <!-- >>搜索框 -->
            <div class="action hdbar-action__search">
                <slot name="search" />
            </div>
 
            <!-- >>右侧 -->
            <div class="action hdbar-action__right">
                <slot name="right" />
            </div>
        </div>
    </div>
</template>

<script>
/**
 * @Desc     Vue自定义导航条headerBar
 * @Time     andy by 2020-10-06
 * @About    Q:282310962  wx:xy190310
 */
    export default {
        props: {
            // 是否返回
            back: { type: [Boolean, String], default: true },
            // 标题
            title: { type: String, default: '' },
            // 标题颜色
            color: { type: String, default: '#fff' },
            // 背景颜色
            bgcolor: { type: String, default: '#22d59c' },
            // 标题是否居中
            center: { type: [Boolean, String], default: false },
            // 搜索框
            search: { type: [Boolean, String], default: false },
            // 是否固定
            fixed: { type: [Boolean, String], default: false },
            // 背景透明
            transparent: { type: [Boolean, String], default: false },
            // 设置层级
            zIndex: { type: [Number, String], default: '2021' },
        },
        data() {
            return {}
        },
        methods: {},
    }
</script>

image

image

image

<header-bar :back="true" :bgcolor="linear-gradient(to right, #f726ff, #2acfff)" color="#ff0" center transparent>
    <template #backIco><i class="iconfont icon-close"></i></template>
 
    <div slot="title">
    <img src="~/assets/img/logo.png" height="14" /> <em>Nuxt</em>
    </div>
 
    <div slot="right" class="ml-20" @click="$toast('搜索~~')"><i class="iconfont icon-search"></i></div>
    <div slot="right" class="ml-20"><i class="iconfont icon-choose"></i></div>
    <div slot="right" class="ml-20"><van-button type="primary" size="mini" @click="saveData">保存</van-button></div>
</header-bar>

image

image

image

<header-bar :back="true" bgcolor="linear-gradient(to right, #6126ff, #ff21ee)" color="#ff0" center>
    <div slot="backIco"><i class="iconfont icon-close"></i></div>
    <div slot="search" class="flex-c flex1">
        <input class="ipt flex1" placeholder="搜索关键字..." />
    </div>
    <div slot="right" class="ml-30"> <i class="iconfont icon-shoucang"></i></div>
    <div slot="right" class="ml-30"> <i class="iconfont icon-female"></i></div>
</header-bar>

Nuxt自定义Tabbar组件

image

<template>
    <div class="tab-bar" :class="{'fixed': fixed}">
        <div class="tab-bar__wrap flexbox flex-alignc" :style="{'background': bgcolor}">
            <div v-for="(item,index) in tabs" :key="index" class="navigator" :class="currentTabIndex == index ? 'on' : ''" @click="switchTabs(index, item)">
                <div class="ico" :class="{'dock': item.dock}">
                    <i v-if="item.dock" class="dock-bg" :style="{'background': item.dockBg ? item.dockBg : activeColor}"></i>
                    <i v-if="item.icon" class="iconfont" :class="item.icon" :style="{'color': (currentTabIndex == index && !item.dock ? activeColor : color), 'font-size': item.iconSize}"></i>
                    <img v-if="item.iconImg" class="iconimg" :src="currentTabIndex == index && !item.dock ? item.selectedIconImg : item.iconImg" :style="{'font-size': item.iconSize}" />
                    <em v-if="item.badge" class="nuxt__badge">{{item.badge}}</em>
                    <em v-if="item.dot" class="nuxt__badge-dot"></em>
                </div>
                <div class="txt" :style="{'color': (currentTabIndex == index ? activeColor : color)}">{{item.text}}</div>
            </div>
        </div>
    </div>
</template>
<script>
  export default {
    props: {
        current: { type: [Number, String], default: 0 },
        // 背景颜色
        bgcolor: { type: String, default: '#fff' },
        // 颜色
        color: { type: String, default: '#999' },
        // 点击后颜色
        activeColor: { type: String, default: '#22d59c' },
        // 是否固定
        fixed: { type: [Boolean, String], default: false },
        // tab选项
        tabs: {
            type: Array,
            default: () => null
        }
    },
    data() {
      return {
          currentTabIndex: this.current
      }
    },
    created() {
        const _pagePath = this.$route.path
        this.tabs.map((val, index) => {
            if(val.pagePath == _pagePath) {
                this.currentTabIndex = index
            }
        })
    },
    methods: {
        switchTabs(index, item) {
            this.currentTabIndex = index
            this.$emit('click', index)
            if(item.pagePath) {
                this.$router.push(item.pagePath)
            }
        }
    },
  }
</script>

image

image

<tab-bar bgcolor="#b6ffff" @click="handleTabbar" :tabs="[
    {
        icon: 'icon-tianjia',
        text: 'Home',
    },
    {
        icon: 'icon-shezhi',
        text: 'Manage',
        badge: 1
    },
    {
        icon: 'icon-male',
        text: 'Ucenter',
        dot: true
    },
    ]"
/>
// tabbar点击事件
handleTabbar(index) {
    this.$toast('tabbar索引值:' + index);
},

另外还支持咸鱼凸起效果,只需配置 dock: true 属性即可。根据项目需要支持自定义多个tab选项。

image

image

<tab-bar bgcolor="#7fa1ff" color="#fff" activeColor="#fb4e30" :tabs="[
    {
        icon: 'icon-face',
        text: 'Face',
        dot: true,
        iconSize: '24px',
    },
    {
        //icon: 'icon-tianjia',
        iconImg: 'https://gw.alicdn.com/tfs/TB1CoEwVrvpK1RjSZFqXXcXUVXa-185-144.png?getAvatar=1',
        text: '咸鱼',
        dock: true,
        dockBg: '#fb4e30',
        iconSize: '.64rem',
    },
    {
        icon: 'icon-search',
        text: '搜索',
    },
    ]"
/>

okey,基于Nuxt自定义仿咸鱼导航组件就分享到这里。希望对大家有所帮助!!✍✍

最后附上一个基于Nuxt/Vue自定义弹框组件
https://segmentfault.com/a/1190000027085208

web前端开发爱好者,专注于前端h5、jquery、vue、react、angular等技术研发实战项目案例。

723 声望
272 粉丝
0 条评论
推荐阅读
Vite4-MobileGPT:基于vue3+vant4移动端仿ChatGPT聊天模板
随着最近openAi推出了Iphone版ChatGPT应用APP。标志着chatgpt已经步入了移动领域。闲暇之余运用vite4.x构建了一个mobile版chatgpt聊天实例。vue3-mobileGPT 支持白色/暗黑两种主题模式。技术栈编辑器:Cursor框架...

xiaoyan2017阅读 435

「多图预警」完美实现一个@功能
一天产品大大向 boss 汇报完研发成果和产品业绩产出,若有所思的走出来,劲直向我走过来,嘴角微微上扬。产品大大:boss 对我们的研发成果挺满意的,balabala...(内心 OS:不听,讲重点)产品大大:咱们的客服 I...

wuwhs40阅读 4.7k评论 5

封面图
【已结束】SegmentFault 思否写作挑战赛!
SegmentFault 思否写作挑战赛 是思否社区新上线的系列社区活动在 2 月 8 日 正式面向社区所有用户开启;挑战赛中包含多个可供作者选择的热门技术方向,根据挑战难度分为多个等级,快来参与挑战,向更好的自己前进!

SegmentFault思否20阅读 5.6k评论 10

封面图
过滤/筛选树节点
又是树,是我跟树杠上了吗?—— 不,是树的问题太多了!🔗 相关文章推荐:使用递归遍历并转换树形数据(以 TypeScript 为例)从列表生成树 (JavaScript/TypeScript) 过滤和筛选是一个意思,都是 filter。对于列表来...

边城18阅读 7.7k评论 3

封面图
Vue2 导出excel
2020-07-15更新 excel导出安装 {代码...} src文件夹下新建一个libs文件夹,新建一个excel.js {代码...} vue页面中使用 {代码...} ===========================以下为早期的文章今天在开发的过程中需要做一个Vue的...

原谅我一生不羁放歌搞文艺14阅读 19.9k评论 9

用了那么久的 SVG,你还没有入门吗?
其实在大部分的项目中都有 直接 或 间接 使用到 SVG 和 Canvas,但是在大多数时候我们只是选择 简单了解 或 直接跳过,这有问题吗?没有问题,毕竟砖还是要搬的!

熊的猫17阅读 1.5k评论 2

封面图
嘿,vue中keep-alive有个「大坑」你可能还不知道
背景是这样的,我们使用vue2开发一个在线客服使用的IM应用,基本布局是左边是访客列表,右边是访客对话,为了让对话加载更友好,我们将对话的路由使用&lt;keep-alive&gt;缓存起来。但是如果将所有对话都缓存,未...

wuwhs12阅读 2.5k

封面图

web前端开发爱好者,专注于前端h5、jquery、vue、react、angular等技术研发实战项目案例。

723 声望
272 粉丝
宣传栏