NavBar 导航栏、Tabbar 标签栏布局封装

448 阅读1分钟

NavBar 导航栏、Tabbar 标签栏布局 ``

<template>
  <div class="Navigation">
    <van-nav-bar
      v-if="showTopbar"
      :border="border"
      :fixed="fixed"
      :left-arrow="!!leftRoute || leftArrow"
      :left-text="leftText"
      :placeholder="placeholder"
      :right-text="rightText"
      :safe-area-inset-top="safeAreaInsetTop"
      :title="$slots.title ? undefined : customTitle"
      :z-index="zIndex"
      @click-left="onClickLeft"
      @click-right="onClickRight"
    >
      <template #title>
        <slot name="title"></slot>
      </template>
      <template #right>
        <slot name="right"></slot>
      </template>
    </van-nav-bar>
    <slot name="extend"></slot>
    <div class="Navigation__body">
      <slot></slot>
    </div>
    <van-tabbar
      v-if="showTabbar"
      :placeholder="true"
      :safe-area-inset-bottom="true"
      active-color="#1989fa"
      route
    >
      <van-tabbar-item icon="apps-o" name="home" to="/index"> 工作台</van-tabbar-item>
      <van-tabbar-item icon="cluster-o" name="contact" to="/contact">通讯录</van-tabbar-item>
      <van-tabbar-item
        :badge="unreadMessageCount"
        icon="comment-o"
        name="notification"
        to="/notification-center"
        >消息
      </van-tabbar-item>
      <van-tabbar-item icon="user-o" name="user" to="/user"></van-tabbar-item>
    </van-tabbar>
  </div>
</template>

<script>
import { mapState } from 'vuex'

export default {
  props: {
    title: String,
    leftText: String,
    rightText: String,
    leftArrow: Boolean,
    leftRoute: [Object, String],
    rightRoute: [Object, String],
    placeholder: {
      type: Boolean,
      default: true
    },
    safeAreaInsetTop: {
      type: Boolean,
      default: true
    },
    fixed: {
      type: Boolean,
      default: true
    },
    border: {
      type: Boolean,
      default: true
    },
    zIndex: {
      type: [Number, String],
      default: 99
    },
    showTopbar: {
      type: Boolean,
      default: true
    },
    showTabbar: {
      type: Boolean,
      default: false
    },
    active: [Number, String]
  },

  computed: {
    ...mapState({
      unreadMessageCount: state => state.app.unreadMessageCount
    }),
    customTitle() {
      return this.title || this.$route.meta.title
    }
  },

  methods: {
    onClickLeft() {
      if (this.$listeners['click-left']) {
        this.$emit('click-left')
      } else {
        // 点击左侧箭头一律返回上一页面
        this.$router.back()
      }
    },

    onClickRight() {
      if (this.$slots.right) {
        return
      }

      if (this.$listeners.clickRight || this.$listeners['click-right']) {
        return this.$emit('click-right')
      }

      if (this.rightRoute) {
        this.$router.push(this.rightRoute)
      }
    }
  }
}
</script>

<style lang="less" scoped>
.Navigation {
  display: flex;
  flex-direction: column;
  width: 100vw;
  height: 100vh;
}

.Navigation__body {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;

  &::-webkit-scrollbar {
    display: none !important;
  }
}

/deep/ .van-nav-bar .van-icon {
  color: #323233 !important;
}

/deep/ .van-nav-bar__left .van-nav-bar__text {
  color: #323232 !important;
}
</style>

# Navigation 组件

包含了 NavBar 导航栏、Tabbar 标签栏布局。

## 使用

```html
<navigation title="联系人" right-text="新增联系人" @click-right="onClickRight">
  <template #extend>
    <van-search placeholder="搜索" />
  </template>

  <!-- 联系人列表 -->
</navigation>

<navigation>
  <template #title>
    <span>联系人</span>
  </template>
  <template #right>
    <!-- 自定定义 right slot,click-right 事件不会触发 -->
    <span @click="onClickRight">新增联系人</span>
  </template>

  <!-- 联系人列表 -->
</navigation>

组件参数

参数说明类型默认值
title导航栏标题string
leftText左侧返回按钮文字string
rightText右侧按钮文字string
rightRoute右侧按钮点击之后跳转的路由string, VueRoute
showTabbar是否显示底部 Tabbar 标签栏booleanfalse
border是否显示下边框booleantrue
placeholder固定在顶部时,是否在标签位置生成一个等高的占位元素booleantrue
safeAreaInsetTop是否开启顶部安全区适配booleantrue
zIndex导航栏 z-indexstring, number1

Slots

名称说明
title自定义标题
left自定义左侧返回区域内容
right自定义右侧区域内容
extend自定义固定在 NavBar 下方区域内容

Events

事件名说明回调参数
click-right点击右侧区域时触发 (如果定义了 right slot,事件不触发)