uniapp使用vue3语法构建自定义导航栏,适配小程序胶囊

具体代码

<template>
	<view class="nav-wrapper-container" :style="'height:'+navBarHeight +'px'">
		<view class="nav-status-container" :style="'height:'+navstatusBarHeight +'px;'" />

		<view v-if="isCustom" class="nav-content-container" :style="'height:'+navContentHeight +'px;'">
			<slot name="left">
			</slot>
			<slot name="middle"> </slot>
			<view :style="'width:'+navPaddingRight+'px;'+'height:40px'"></view>
		</view>
		<view v-else class="nav-content-container" :style="'height:'+navContentHeight +'px;'">
			<image v-if="!isInTab" class="nav-content-left" src="../../static/back.png" mode="widthFix"
				@click="handleClickBack" />
			<view class="nav-content-middle">
				<text>{{titleText}}</text>
			</view>
		</view>
		<slot name="bottom" :style="'height:'+bottomComponentHeight +'px;'"></slot>
	</view>
</template>

<script setup>
	import {
		onBeforeMount,
		ref,
		defineProps,
		defineEmits
	} from 'vue'

	const emits = defineEmits(['init-height'])
	/**
	 * 整个导航栏的高度
	 */
	const navBarHeight = ref(0)
	/**
	 * 状态栏高度
	 */
	const navstatusBarHeight = ref(0)

	/**
	 * 内容高度
	 */
	const navContentHeight = ref(0)

	/**
	 * 距离右侧胶囊的padding-right
	 */
	const navPaddingRight = ref(0)


	/**
	 * 是否在tab页
	 */
	const isInTab = getCurrentPages().length == 1

	/**
	 * 获取导航栏尺寸
	 */
	const initNavSize = () => {
		///获取系统信息
		const {
			statusBarHeight,
			uniPlatform
		} = uni.getSystemInfoSync()
		///是否支持这个方法
		const isNoSupportGetMenuButton = (uniPlatform == "app") || (uniPlatform == "web") || (uniPlatform == "mp-lark")
		///内容高度
		let contentHeight = 0
		///计算内容高度
		if (!isNoSupportGetMenuButton) {
			///拿到胶囊信息
			const menuButton = uni.getMenuButtonBoundingClientRect()
			contentHeight = (menuButton.top - statusBarHeight) * 2 + menuButton.height
			navPaddingRight.value = menuButton.width + 24
		} else {
			contentHeight = 48
			navPaddingRight.value = 24

		}
		///赋值状态栏高度
		navstatusBarHeight.value = statusBarHeight
		///赋值内容高度
		navContentHeight.value = contentHeight
		///总的高度=内容高度+状态栏高度+bottom组件高度
		console.log("props.bottomComponentHeight is " + props.bottomComponentHeight)
		console.log("statusBarHeight is " + statusBarHeight)
		console.log("contentHeight is " + contentHeight)
		navBarHeight.value = statusBarHeight + contentHeight + parseInt(props.bottomComponentHeight)
		emits('init-height', navBarHeight.value)

	}

	/**
	 * 返回
	 */
	const handleClickBack = () => {
		uni.navigateBack({
			delta: 1 // 返回的页面数,这里设置为1表示返回上一页
		});
	}


	const props =
		defineProps({
			///标题
			titleText: {
				type: String,
				default: ""
			},
			///是否使用自定义插槽
			isCustom: {
				type: Boolean,
				default: false
			},
			///bottom组件高度
			bottomComponentHeight: {
				type: String,
				default: "0"
			}

		})
	onBeforeMount(() => {
		initNavSize()
	})
</script>

<style lang="less">
	.nav-wrapper-container {
		height: var(--status-bar-height);
		width: 100%;
		position: fixed;
		width: 100%;
		top: 0;
		background-color: transparent);
		left: 0;
		z-index: 2;
		align-items: center;
	}

	.nav-status-container {
		width: 100%
	}

	.nav-content-container {
		width: 100%;
		display: flex;
		position: relative;
		align-items: center;
	}

	.nav-content-left {
		width: 40rpx;
		margin-left: 12rpx;
	}

	.nav-content-middle {
		position: absolute;
		left: 50%;
		transform: translate(-50%);
	}
</style>

使用方法:
使用默认配置:

<navbar titleText="这是标题"></navbar>

使用自定义插槽:

		<navbar :isCustom="true" @init-height="initNavHeight" data-eventsync="true" bottomComponentHeight="45">
			<template v-slot:left>
				<image class="nav-content-left" src="../../static/back.png" mode="widthFix" @click="handleClickBack" />
			</template>
			<template v-slot:middle>
				<view class="search-bar-middle" @click="handlerClickSearch()">
					<image src="../../static/search.png" mode="widthFix" style="width: 24rpx"></image>
					<text class="search-bar-middle-text">搜索内容、体系、文章</text>
				</view>
			</template>
			<template v-slot:bottom>
				<classify-menu-bar :tabArr="tabArr" @on-change-tab="onChangeTab" class="classify-top-container"></classify-menu-bar>
			</template>
		</navbar>

一共有三个插槽:
● left: 左侧
● middle:居中
● bottom:固定底部 (需用传递属性,作为底部buttom的高度)

在这里插入图片描述

  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3 和 UniApp 中,可以使用自定义导航栏来实现个性化的导航栏样式和功能。下面是一种实现方式: 1. 在 App.vue 文件中,可以设置全局的导航栏样式和功能。你可以在顶部放置一个自定义导航栏组件,并设置相应的样式和事件。例如: ```vue <template> <div> <!-- 自定义导航栏 --> <custom-navbar></custom-navbar> <!-- 页面内容 --> <router-view></router-view> </div> </template> <script> import CustomNavbar from '@/components/CustomNavbar.vue'; export default { components: { CustomNavbar, }, }; </script> ``` 2. 创建一个 CustomNavbar.vue 组件,并在其中定义导航栏的样式和事件。例如: ```vue <template> <nav class="custom-navbar"> <div class="left"> <!-- 左侧按钮 --> </div> <div class="title"> <!-- 标题 --> </div> <div class="right"> <!-- 右侧按钮 --> </div> </nav> </template> <script> export default { methods: { // 左侧按钮点击事件 handleLeftClick() { // 处理左侧按钮点击事件 }, // 右侧按钮点击事件 handleRightClick() { // 处理右侧按钮点击事件 }, }, }; </script> <style scoped> .custom-navbar { /* 导航栏样式 */ } .left, .right { /* 左侧和右侧按钮样式 */ } .title { /* 标题样式 */ } </style> ``` 3. 在需要自定义导航栏的页面中,可以通过导入 CustomNavbar 组件来替换全局的导航栏。例如: ```vue <template> <div> <!-- 自定义导航栏 --> <custom-navbar></custom-navbar> <!-- 页面内容 --> <!-- ... --> </div> </template> <script> import CustomNavbar from '@/components/CustomNavbar.vue'; export default { components: { CustomNavbar, }, }; </script> ``` 通过以上步骤,你可以在 Vue3 和 UniApp 中实现自定义导航栏。你可以根据需要自定义导航栏的样式和功能,来满足不同的设计需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值