uniapp 模仿 Android的Menu菜单栏

下面这张图就是我们要模拟的菜单功能 

一、模拟的逻辑

1. 我们使用uni-popup组件(记得要用hbuilder X导入该组件)
uni-app官网

2. 将组件内的菜单自定义样式

二、uniapp代码 写法vue3

<template>
	<view>
		<uni-popup ref="showMenu" type="right" mask-background-color="rgba(0,0,0,0.1)">
			<view class="popup-content">
				<view @click="doAction(1)">哈哈哈哈</view>
				<view @click="doAction(2)">嘻嘻嘻嘻</view>
				<view @click="doAction(3)">呜呜呜呜</view>
			</view>
		</uni-popup>
	</view>
</template>

<script setup>
	import {ref,onMounted} from "vue";
	let showMenu = ref(null);
    onMounted({
        showPopup(); 
    });
	//显示菜单
	const showPopup = () => {
		showMenu.value.open();
	}
	//处理菜单选项的动作
	const doAction = (index) => {
		console.log(index);
		showMenu.value.close();
	}

</script>

<style scoped lang="scss">
	.popup-content {
		width: 300rpx;
		background-color: #F8f8f8;
		border-radius: 8px;
		padding: 16px;
		color: #e5e5e5;
		margin-top: 100rpx;
		margin-right: 16rpx;
		view{
			padding: 20rpx;
		}
	}
</style>

目前存在的问题:使用uni-popup是无法遮挡tabBar,因为tabBar是原生组件,这里的解决方案是subNVue(pages.json 页面路由 | uni-app官网
 

三、subNVue改进版

1. subNVue 是 vue 页面的原生子窗体。用于解决App中 vue 页面中的层级覆盖和原生界面灵活自定义用的。

2. 它不是全屏页面,也不是组件,就是一个原生子窗体。它是一个 nvue 页面,使用 weex 引擎渲染。

=》翻译一下就是,它不能用文件去定义,而是用配置,就像JavaScript中用代码创建一个div标签一样,我们在page.json文件中配置它的宽度、高度、背景色。

使用subNVue逻辑

1. 在page.json中在一个页面下,定义一个subNVue子窗体。
=》解释:也就是该窗体属于当前页面,在当前页面上层出现。

2. 定义一个nvue文件,让它的内容,在subNVue子窗体内显示

3. 在index.vue野蛮,获取到子窗体,调用它的显示方法,显示子窗体和它的内容

 具体使用方法要看文档uni-app subNVue 原生子窗体开发指南 - DCloud问答,我直接就将我的代码粘贴出来

1.在page.json配置subNVue子窗体

项目结构

pages

        index 

               index.vue

                subNVue
                        menu-sub.nvue

{
	"pages": [{
		"path": "pages/index/index",
		"style": {
			"navigationStyle": "custom", //禁用原生导航栏,也可以使用titleNView为false
			"app-plus": {
				"bounce": "none", //关闭页面回弹效果
				"subNVues": 
				[
					{
						"id": "custome-menu", //subNVue 的 id,可通过 uni.getSubNVueById('drawer') 获取
						"path": "pages/index/subNVue/menu-sub", // nvue 路径
						"type": "popup",                        //只有设置为popup类型,mask才管用
						"style": { 
							"position": "absolute",  
							"dock": "bottom",  
							"width": "40%",  
							"height": "40%",  
							"background":"transparent",
							"mask":"rgba(0,0,0,0)",
							"zindex": 999,
							"right": "16rpx"
						}
					}
				]
			}
		}
	}]
}

2.子窗体显示的内容

<!-- 子窗体显示的内容 -->
<template>
	<view class="popup-content">
		<view class="t1" @click="doAction(1)">长歌行</view>
		<view class="t1" @click="doAction(2)">落日圆</view>
		<view class="t1" @click="doAction(3)">我欲封天</view>
		<view class="t1" @click="doAction(4)">万古长夜</view>
		<view class="t1" @click="doAction(5)">清晨</view>
	</view>
</template>

<script setup>
	import {ref} from "vue";

	//处理菜单选项的动作
	const doAction = (index) => {
		uni.showToast({
			title: index
		});
		//关闭菜单栏
		const subNVue = uni.getSubNVueById('custome-menu');
		subNVue.hide('fade-out',300);
	}
</script>

<style scoped lang="scss">
	.popup-content {
		width: 300rpx;
		background-color: #F8f8f8;
		border-radius: 8px;
		padding: 16px;
		color: $normal-font-color;
		margin-top: 100rpx;
		margin-right: 16rpx;
		.t1{
			padding: 20rpx;
		}
	}
</style>

 3. 在index.vue页面触发显示子窗体和它的内容

<template>
	
</template>

<script setup>
    import {onMounted} from "vue";

	onMounted(() => {
        showMenu(); 
    });
	
	
	//1. 显示菜单
	const showMenu = () => {
		const subNVue = uni.getSubNVueById('custome-menu');  //通过 id 获取 nvue 子窗体
		subNVue.show('slide-in-right', 300, function() {
			// console.log("打开了菜单栏");
		});
	}
	
	
	
</script>

<style scoped lang="scss">
	
</style>

猜你喜欢

转载自blog.csdn.net/tengyuxin/article/details/134106759