美文网首页
vue2自定义导航栏(Taro+navBar)

vue2自定义导航栏(Taro+navBar)

作者: T_guo | 来源:发表于2023-06-07 15:26 被阅读0次

    背景

    现在小程序导航栏很多时候需要自定义,这里简单的封装了一个自定义导航栏,(菜鸟一名有不对的地方勿喷欢迎留言指正)

    <template>
      <view>
        <view
          class="nav-bar"
          :style="{
            paddingTop: statusBarHeight + 'px',
            backgroundColor: barBgColor,
          }"
        >
          <view class="nav-bar-layout">
            <view
              class="nav-bar-layout-left"
              @tap="clickEvent()"
              hoverClass="hover"
            >
              <image class="nav-bar-layout-left-icon" :src="topLeftIcon"></image>
            </view>
            <view
              class="nav-bar-layout-title"
              :style="{ color: titleColor, fontSize: titleSize + 'px' }"
              >{{ title }}</view
            >
          </view>
          <view class="nav-bar-line" v-show="!isTop || mode == 0"></view>
        </view>
        <view
          v-if="navData.showTopFill"
          class="nav-bar-null-view"
          :style="{ height: topHeight + 'px' }"
        ></view>
        <slot></slot>
      </view>
    </template>
    
    <script >
    import Taro, { getCurrentInstance } from "@tarojs/taro";
    
    export default {
      name: "nav-bar",
      props: {
        title: {
          type: String,
          default: "",
        },
        titleSize: {
          type: Number,
          default: 16,
        },
        mode: {
          type: Number,
          default: 0,
        },
        scrollTop: {
          type: Number,
          default: 0,
        },
        changePosition: {
          type: Number,
          default: 10,
        },
        controlBack: {
          type: Boolean,
          default: false,
        },
      },
      data() {
        return {
          statusBarHeight: 20,
          topHeight: 64,
          isTop: true,
          navData: null,
          modeData: {
            0: {
              //顶部固定
              barBgColorTop: "#ffffff",
              barBgColorScroll: "#ffffff",
              titleColorTop: "#2A2B2E",
              titleColorScroll: "#2A2B2E",
              topLeftIconTop: "../../assets/back_black.png",//返回的白色箭头
              topLeftIconScroll: "../../assets/back_black.png",//返回的黑色箭头
              showTopFill: true,
            },
            1: {
              //透明
              barBgColorTop: "#00000000",
              barBgColorScroll: "#ffffff",
              titleColorTop: "#ffffff",
              titleColorScroll: "#2A2B2E",
              topLeftIconTop: "../../assets/back.png",//返回的白色箭头
              topLeftIconScroll: "../../assets/back_black.png",//返回的黑色箭头
              showTopFill: false,
            },
            2: {
              //透明
              barBgColorTop: "#00000000",
              barBgColorScroll: "#ffffff",
              titleColorTop: "#2A2B2E",
              titleColorScroll: "#2A2B2E",
              topLeftIconTop: "../../assets/back_black.png",//返回的白色箭头
              topLeftIconScroll: "../../assets/back_black.png",//返回的黑色箭头
              showTopFill: false,
            },
          },
        };
      },
      watch: {
        mode: {
          handler(newVal, oldVal) {
            try {
              if (this.modeData[newVal]) {
                this.navData = this.modeData[newVal];
              }
            } catch (e) {}
          },
          immediate: true,
        },
        scrollTop: {
          handler(newVal, oldVal) {
            if (newVal > this.changePosition && this.isTop) {
              this.isTop = false;
            }
            if (newVal <= this.changePosition && !this.isTop) {
              this.isTop = true;
            }
            // console.log("==scrollTop==", newVal);
          },
          immediate: true,
        },
      },
      computed: {
        topLeftIcon() {
          return this.isTop
            ? this.navData.topLeftIconTop
            : this.navData.topLeftIconScroll;
        },
        barBgColor() {
          return this.isTop
            ? this.navData.barBgColorTop
            : this.navData.barBgColorScroll;
        },
        titleColor() {
          return this.isTop
            ? this.navData.titleColorTop
            : this.navData.titleColorScroll;
        },
      },
      destroyed() {},
      mounted() {
        try {
          const res = Taro.getSystemInfoSync();
          this.statusBarHeight = res.statusBarHeight;
          this.topHeight = 44 + res.statusBarHeight;
        } catch (e) {}
      },
      methods: {
        clickEvent() {
          if (this.controlBack) {
            this.$emit("barBack", true);
          } else {
            Taro.navigateBack({});
          }
        },
      },
    };
    </script>
    
    <style lang="scss">
    .nav-bar {
      z-index: 9999;
      position: fixed;
      top: 0;
      right: 0;
      left: 0;
      box-sizing: border-box;
      display: flex;
      flex-direction: column;
    
      .nav-bar-layout {
        width: 375px;
        height: 44px;
        position: relative;
    
        .nav-bar-layout-left {
          z-index: 10;
          box-sizing: border-box;
          position: absolute;
          top: 0px;
          left: 0px;
          padding: 10px 0px 10px 16px;
    
          .nav-bar-layout-left-icon {
            width: 24px;
            height: 24px;
          }
        }
    
        .nav-bar-layout-title {
          position: absolute;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
          font-weight: 550;
          font-size: 16px;
          line-height: 22px;
          text-align: center;
          color: #2a2b2e;
          display: flex;
          align-items: center;
          justify-content: center;
        }
      }
    
      .nav-bar-line {
        width: 100%;
        height: 0.25px;
        background-color: #f0f0f0;
        box-shadow: 0px 0.5px 0px rgba(0, 0, 0, 0.12);
      }
    }
    .nav-bar-null-view {
      width: 375px;
    }
    </style>
    

    使用

    <template>
      <nav-bar
        title="标题"
        :scrollTop="scrollTop"
        :mode="1"
        :controlBack="true"
        @barBack="barBack()"
      >
     <!-- @barBack="barBack()"不写默认是返回上一个页面Taro.navigateBack({}); -->
     <!-- 这里写页面代码 -->
      </nav-bar>
    </template>
    
    <script>
     /*导入头文件 ,路径根据自己的具体路径导入*/
    import navBar from "@/components/navBar/navBar.vue";
    export default {
      components: {
        navBar
      },
      data() {
        return {
          scrollTop: 0,
        };
      },
      onPageScroll(res) {
        this.scrollTop = res.scrollTop;
      },
      onShow() {
        console.log("---00---");
      },
      mounted() {},
      methods: {
        /*返回按钮监听*/
        barBack() {
           /*返回按钮监听,可以拦截返回事件,重写方法,根据具体的业务需求处理返回逻辑*/
          console.log("---返回按钮监听---");
         /*比如当我们从扫码进入这个页面,这个时候点击返回按钮没有任何响应(实际上是因为报错了,因为这个时候Taro.navigateBack没有上一个页面),我们就需要在这里做监听,处理返回逻辑*/
        /*例如下:*/ 
          Taro.navigateBack({
            success: function(res) {
              console.log(res);
              // Taro.navigateBack({});
            },
            fail: function(res) {
              console.log( res);
              Taro.switchTab({ url: "/pages/index/index" });
            },
            complete: function(res) {
              console.log( res);
            }
          });
      }
    };
    </script>
    
    

    相关文章

      网友评论

          本文标题:vue2自定义导航栏(Taro+navBar)

          本文链接:https://www.haomeiwen.com/subject/fdwhjdtx.html