Nuxt/Vue自定義導航欄Topbar+標籤欄Tabbar組件

基於Vue.js實現自定義Topbar+Tabbar組件|仿鹹魚底部凸起導航html

最近一直在倒騰Nuxt項目,因爲Nuxt.js是基於Vue.js的服務端渲染框架,只要是會vue,基本能很快上手了。vue

通常移動端項目,頂部導航/底部Tab功能是少不了的。本想着使用Vant組件庫,但是項目中有個相似鹹魚底部凸起導航功能,通過再三考慮仍是本身造了個自定義Navbar+Tabbar組件。以便之後在其它Vue項目中也能使用。微信

如上圖:在Nuxt項目中應用效果框架

下面就開始進入Nuxt中建立自定義頂部導航條及底部標籤欄的介紹。flex

◆ 開始

在components目錄下新建 headerBar.vuetabBar.vue 頁面。this

而後在 plugins 目錄下的 componentsInstall.js 文件中引入便可。flexbox


 

◆ 自定義導航條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>
/**
 * @Desc     Vue自定義導航條headerBar
 * @Time     andy by 2020-10-06
 * @About    Q:282310962  wx:xy190310
 */
<script>
    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>

支持自定義背景、顏色、圖標、標題居中、搜索欄,右側按鈕支持圖標/文字/圖片,還能夠自定義圓點、事件處理等功能。spa

<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="16" /> <em>Nuxt</em>
    </div>

    <div slot="right" class="ml-20"><i class="iconfont icon-search"></i></div>
    <div slot="right" class="ml-20" @click="$toast('選擇~~')"><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>

<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="Search..." value="搜索關鍵字..." />
    </div>
    <div slot="right" class="ml-20"> <i class="iconfont icon-shoucang"></i></div>
    <div slot="right" class="ml-20"> <i class="iconfont icon-female"></i></div>
</header-bar>

<header-bar :back="true" bgcolor="#fcd5ff" color="#c24cff" center>
    <div slot="backIco" class="flex-c"><i class="iconfont icon-arrL"></i> NUXT自定義導航欄</div>
    <div slot="right"><i class="iconfont icon-male"></i><em class="nuxt__badge">6</em></div>
    <div slot="right"><img src="~/assets/img/logo.png" height="12" /><em class="nuxt__badge-dot"></em></div>
</header-bar>


 

◆ 自定義底部導航tabBar

<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>

支持自定義文字/圖標、背景色、文字顏色/選中顏色、是否固定、點擊事件(返回點擊選項索引值) 等功能。nuxt

<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 便可實現相似鹹魚凸起按鈕效果。3d

<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: '搜索',
    },
    ]"
/>

ok,基於Vue/Nuxt自定義頂部/底部導航組件就介紹到這裏。但願對你們有所幫助哈!😐

最後附上

基於Vue/Nuxt自定義彈框組件|仿微信彈出框效果

Flutter/Dart沉浸式狀態欄|flutter自定義導航條

相關文章
相關標籤/搜索