uniapp微信小程序封装navbar组件

一、 最终效果

二、实现了功能

json 复制代码
1、nav左侧返回icon支持自定义点击返回事件(默认返回上一步)
2、nav左侧支持既显示返回又显示返回首页icon
3、nav左侧只显示返回icon
4、nav左侧只显示返回首页icon
5、nav左侧自定义left插槽
6、nav中间支持title命名
7、nav中间支持center插槽
8、支持自定义背景颜色:backgroundColor
9、支持修改icon大小、颜色
10、支持导航栏文字颜色自定义
11、支持自定义返回指定页面并可以传参(goBackUrl、urlParam)
12、支持自定义导航栏高度(默认设备高度)

三、navbar参数配置

1、代码示例:

html 复制代码
<navbar titleText="登录页面"/>

2、 配置参数(Attributes)

参数 说明 类型 默认值
backgroundColor 导航栏背景颜色 String #355db4
navCustomHeight 自定义导航栏高度(单位rpx) number 0
color 导航栏文字颜色 String #fff
fontSize 导航栏文字大小(单位rpx) number 32
iconSize 导航栏图标大小 number 18
iconColor 导航栏图标颜色 String #fff
titleText 导航栏标题 String -
backMain 是否显示返回首页图标 boolean false
isGoBack 是否显示返回图标 boolean false
isGoBackEvent 是否自定义写返回事件 boolean false
goBackUrl 返回指定页面路径 string -
urlParam 返回指定页面路径参数 string -

3、 Events

事件名 说明 返回值
goBack 自定义返回事件 -

4、Slot

事件名 说明
left 左侧具名插槽
center 导航栏标题插槽)
- 默认插槽

四、源码

html 复制代码
<template>
  <view
    class="nav"
    :style="{
      height: navCustomHeight ? `${navCustomHeight}rpx` : allnavHeight,
      background: props.backgroundColor
    }"
  >
    <view :style="'height:' + status + 'rpx;'"></view>
    <view class="navBar" :style="'height:' + navHeight + 'rpx;max-height:' + navHeight + 'rpx'">
      <view class="nav_bar_left" :style="{ color: props.color }">
        <!-- 既显示返回又显示返回首页icon -->
        <view v-if="isGoBack && backMain" class="back-home">
          <view class="back flex-box flex-ver" @tap="goBack" v-if="isGoBack">
            <uni-icons class="imageClass" :size="iconSize" type="left" :color="iconColor"></uni-icons>
          </view>
          <view class="line"></view>
          <view class="home flex-box flex-ver" @tap="goHome" v-if="backMain">
            <uni-icons class="imageClass" :size="iconSize" type="home" :color="iconColor"></uni-icons>
          </view>
        </view>
        <!-- 只显示返回icon -->
        <view v-else-if="isGoBack" class="flex-box flex-ver-v" @click.stop="goBack">
          <uni-icons class="imageClass" :size="iconSize" type="left" :color="iconColor"></uni-icons>
        </view>
        <!-- 只显示返回首页icon -->
        <view v-else-if="backMain" class="flex-box flex-ver-v" @click.stop="goHome">
          <uni-icons class="imageClass" :size="iconSize" type="home" :color="iconColor"></uni-icons>
        </view>
        <!-- 自定义插槽 -->
        <view v-else class="flex-box flex-ver-v">
          <slot name="left" />
        </view>
      </view>
      <view class="nav-title" v-if="titleText">
        <view :style="textStyle">{{ titleText }}</view>
      </view>
      <view class="center" v-else>
        <slot name="center" />
      </view>
    </view>
    <slot />
  </view>
</template>

<script setup lang="ts">
interface Search {
  backgroundColor: string; // 导航栏背景颜色--可以是渐变
  navCustomHeight: number; // 自定义导航栏高度
  color: string; // 导航栏文字颜色
  fontSize: number; // 导航栏文字大小
  iconSize: number; // 导航栏图标大小
  iconColor: string; // 导航栏图标颜色
  titleText: string; // 导航栏标题
  backMain: boolean; // 是否显示返回首页图标
  isGoBack: boolean; // 是否显示返回图标
  isGoBackEvent: boolean; // 是否自定义写返回事件
  goBackUrl: string; // 返回的url
  urlParam: string; // 返回的url参数
}
const props = withDefaults(defineProps<Search>(), {
  backgroundColor: "#355db4",
  color: "#fff",
  fontSize: 32,
  iconSize: 18,
  iconColor: "#fff",
  navCustomHeight: 0,
  titleText: "",
  backMain: false,
  isGoBack: false,
  isGoBackEvent: false,
  goBackUrl: "",
  urlParam: ""
});
onLoad(() => {
  setNavSize();
  setStyle();
});
onPageScroll((e: any) => {
  // e.scrollTop 表示当前页面滚动的距离
  console.log(e);
  // 在这里编写你的滚动相关逻辑
});
//状态栏高度
const status = ref(0);
//nav高度
const navHeight = ref(0);
//导航栏高度
const allnavHeight = ref("");
//字体样式
const textStyle = ref("");
// 页面栈的数量
const pages = ref(getCurrentPages().length);
//获取状态栏高度
const setNavSize = () => {
  const app = uni.getSystemInfoSync();
  const menuButtonInfo = uni.getMenuButtonBoundingClientRect();
  let statusBarHeight = app.statusBarHeight || 0;
  status.value = statusBarHeight / (uni.upx2px(100) / 100);
  navHeight.value = menuButtonInfo.height / (uni.upx2px(100) / 100) + 30;
  allnavHeight.value = status.value + navHeight.value + "rpx;";
};
const emits = defineEmits(["goBack"]);
//样式设置
const setStyle = () => {
  textStyle.value = ["color:" + props.color, "font-size:" + props.fontSize + "rpx"].join(";");
};
// 返回上一步
const goBack = () => {
  if (props.goBackUrl != "") {
    uni.redirectTo({
      url: props.goBackUrl + "?" + props.urlParam
    });
  } else {
    // if (props.isGoBack && !props.isGoBackEvent && pages.value > 1) {
    if (props.isGoBack && !props.isGoBackEvent) {
      console.log("后退一步");
      uni.navigateBack();
    } else {
      emits("goBack");
    }
  }
};
// 返回首页
const goHome = () => {
  uni.reLaunch({
    url: "/pages/tabbarPage/tabbarPage"
  });
};
</script>

<style lang="scss">
.nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1;
  width: 100%;
  background-size: cover;
  background-repeat: no-repeat;
  background-position: top;
  .navBar {
    position: relative;
    display: flex;
    align-items: center;
    .nav_bar_left {
      height: inherit;
      position: absolute;
      width: 75px;
      display: flex;
      align-items: center;
      margin-left: 10px;
      .back-home {
        display: flex;
        align-items: center;
        width: 100%;
        background: rgba(255, 255, 255, 0.6);
        border-radius: 16px;
        box-sizing: border-box;
        box-shadow: 0 0 1px rgb(207, 207, 207);
        overflow: hidden;
        .back {
          flex: 1;
        }
        .home {
          flex: 1;
        }
        .line {
          width: 1px;
          height: 20px;
          background: rgba(0, 0, 0, 0.2);
          transform: scaleX(0.5);
        }
      }
      .back-icon {
        display: flex;
        align-items: center;
        width: 32rpx;
        height: 100%;
        margin-left: 20rpx;
        .imageClass {
          display: flex;
          justify-content: center;
          align-items: center;
        }
      }
    }

    .nav-title {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }
    .center {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }
  }
  .flex-box {
    display: -webkit-box;
    display: -webkit-flex;
    display: flex;
  }
  .flex-ver {
    align-items: center;
    justify-content: center;
  }
  .flex-ver-v {
    align-items: center;
  }
}
</style>

相关文章

基于ElementUi再次封装基础组件文档


Vue3+Vite+Ts+Pinia+Qiankun后台管理系统


vue3+ts基于Element-plus再次封装基础组件文档

相关推荐
耶啵奶膘1 小时前
uniapp-小程序地图展示
javascript·小程序·uni-app
SuperherRo14 小时前
Web开发-JS应用&微信小程序&源码架构&编译预览&逆向调试&嵌套资产&代码审计
前端·javascript·微信小程序·源码·逆向
yede14 小时前
微信小程序 - 获取权限
微信小程序·uni-app
黑马源码库miui5208614 小时前
心理咨询法律咨询预约咨询微信小程序系统源码独立部署
微信小程序·小程序·uni-app·php·微信公众平台
有一只柴犬15 小时前
3. 实战(一):Spring AI & Trae ,助力开发微信小程序
人工智能·spring·微信小程序
黑金IT1 天前
借助FastAdmin和uniapp,高效搭建AI智能平台
人工智能·uni-app·php
暮雨哀尘1 天前
微信小程序开发:微信小程序组件应用研究
算法·微信·微信小程序·小程序·notepad++·微信公众平台·组件
狂团商城小师妹1 天前
经销商订货管理系统小程序PHP+uniapp
微信·微信小程序·小程序·uni-app·php·微信公众平台
Bingo_BIG2 天前
uni-app自动升级功能
前端·javascript·uni-app·移动端开发