NafmHeader.vue 4.85 KB
<template>
  <section v-wrap:height="'v'">
    <div class="nav_bar" :class="{bgImgClass:isBgImg}" :style="navObj.barStyle">
      <div class="nav_top_container" v-if="$slots.top">
        <slot name="top" />
      </div>
      <div class="nav_content_container">
        <!-- 左侧 自定义 -->
        <div class="nav_left" v-if="$slots.left" slot="left">
          <slot name="left" />
        </div>
        <!-- 左侧 默认 箭头以及文字描述 -->
        <div class="nav_left" v-else @click="handleBack">
          <i v-if="navObj.barLeftArrow" class="iconfont iconpreviewleft"></i>
          {{navObj.barLeftText}}
        </div>
        <!-- 标题栏 默认 自定义 -->
        <div v-if="$slots.default" v-wrap:height="'v'">
          <div class="nav_title" v-wrap:height="'v'">
            <slot />
          </div>
        </div>
        <!-- 标题栏 -->
        <div class="nav_title" v-else>{{navObj.barTitle}}</div>
        <!-- 右侧插槽 -->
        <div class="nav_right" v-if="$slots.right" slot="right">
          <slot name="right" />
        </div>
      </div>
      <div class="nav_bottom_container" v-if="$slots.bottom">
        <slot name="bottom" />
      </div>
    </div>
  </section>
</template>
<script>
export default {
  name: 'NafmHeader',
  props: {
    bgColor: {
      type: String,
    },
    isBgImg: {
      type: Boolean,
      default: true
    },
    color: {
      type: String
    },
    leftText: {
      type: String
    },
    leftArrow: {
      type: Boolean,
      default: undefined
    },
    title: {
      type: String
    },
    showBack: {
      type: Boolean,
      default: false
    },
    onBack: {
      type: Function,
    }
  },
  computed: {
    navObj () {
      const meta = this.$route.meta
      let leftArrowStatus = true
      if (this.leftArrow != undefined) {
        leftArrowStatus = this.leftArrow
      } else if (meta.leftArrow != undefined) {
        leftArrowStatus = meta.leftArrow
      }

      // 如果设置了背景图片 则不用设置 背景颜色了
      // console.log('this.isBgImg',this.isBgImg)
      const barStyleBg = this.isBgImg ? {} : { background: this.bgColor || meta.bgColor || '#729ae0' }
      // console.log('meta',meta)
      return {
        barStyle: {
          ...barStyleBg,
          color: this.color || meta.color || '#fff'
        },
        barLeftText: this.leftText || meta.leftText || '',
        barTitle: this.title || meta.title || '',
        barLeftArrow: leftArrowStatus
      }
    },
  },
  methods: {
    handleBack () {
      if (this.showBack) {
        this.onBack()
      } else {
        this.$router.back()
      }
      this.$nextTick
    }
  },
  directives: {
    wrap: {
      inserted: function (el, binding, vnode, oldVnode) {
        setTimeout(() => {
          const { arg, value } = binding
          const style = { width: 0, height: 0 }
          for (let i = 0; i < el.childNodes.length; i++) {
            const element = el.childNodes[i];
            if (arg == 'height') {
              if (value == 'h') {
                style.height = Math.max(style.height, element.offsetHeight)
              } else if (value == 'v') {
                style.height = style.height + element.offsetHeight
              }
            } else if (arg == 'width') {
              if (value == 'h') {
                style.width = Math.max(style.height, element.offsetWidth)
              } else if (value == 'v') {
                style.width = style.height + element.offsetWidth
              }
            }
          }

          style.width && (el.style.width = `${style.width}px`)
          style.height && (el.style.height = `${style.height}px`)
        }, 0);
      }
    }
  }
}
</script>
<style lang="less" scoped>
@NavHeight: 45px;
@PaddingSize: 15px;
section {
  width: 100%;
  position: relative;
  z-index: 10;

  .nav_bar {
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    padding: 0 @PaddingSize;
    box-sizing: border-box;

    .nav_content_container {
      min-height: @NavHeight;
      position: relative;
      display: flex;
      align-items: center;
      justify-content: space-between;
    }
  }
  .bgImgClass {
    background: url(../assets/icon/bg_navigation.png) !important;
    background-repeat: no-repeat;
    background-size: 100% !important;
    background-position: center center;
  }
  .nav_left {
    display: flex;
    align-items: center;
    :active {
      opacity: 0.5;
    }
    .iconpreviewleft {
      font-size: 25px;
    }
    img {
      width: 51px;
      height: 51px;
    }
  }
  .nav_title {
    position: absolute;
    left: 0;
    top: 0;
    height: 100%;
    width: 100%;
    min-height: @NavHeight;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
    z-index: -1;
  }
  .nav_right {
    min-width: 100px;
    display: flex;
    align-items: center;
    justify-content: flex-end;
  }
}
</style>