uni-app自定义弹窗

1、项目根目录components目录下创建/modal/modal.vue文件

2、modal.vue文件内容

vue2版本:

<template>
	<view class="modal-container">
		<view class="bg" @tap="maskClose"></view>
		<view class="box">
			<view class="content-box">
				<slot></slot>
			</view>
			<view class="footer">
				<view v-if="cancelVisble" class="item-cancel" @tap="cancel">{{cancelText}}</view>
				<view :class="['item-ok',{'ghost':okGhost}]" @tap="ok">{{okText}}</view>
			</view>
			<view v-if="closable" class="close-btn" @tap="close">
				<image v-if="closeImg" :src="imgs" class="icon-close"></image>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		name:"modal",
		data(){
			return {
				// 取消按钮文字
				cancelText:"取消",
				// 	取消按钮是否显示
				cancelVisble:true,
				// 确认按钮文字
				okText:"确定",
				// 幽灵属性,使按钮背景透明
				okGhost:false,
				// 点击蒙层是否允许关闭
				maskClosable:true,
				// 是否显示关闭按钮
				closable:true,
				closeImg:false,
				imgs:'https://frontend-c.oss-cn-hangzhou.aliyuncs.com/wz-mini-program/v2/icons/close.png'
			}
		},
		props:[
			// 取消按钮文字
			'cancelTextMethod',
			// 	取消按钮是否显示
			'cancelVisbleMethod',
			// 确认按钮文字
			'okTextMethod',
			// 幽灵属性,使按钮背景透明
			'okGhostMethod',
			// 点击蒙层是否允许关闭
			'maskClosableMethod',
			// 是否显示关闭按钮
			'closableMethod',
		],
		onMounted() {
			this.$emit(['cancel','ok']);
		},
		methods:{
			maskClose(){
				if(props.maskClosable){
					// console.log("maskClose")
					this.$emit("cancel")
				}
			},
			close(){
				// console.log("close")
				this.$emit("cancel")
			},
			cancel(){
				// console.log("cancel")
				this.$emit("cancel")
			},
			ok(){
				// console.log("ok")
				this.$emit("ok")
			}
		}
	}
</script>
<style lang="scss" scoped>
	.modal-container{
		position: fixed;
		left: 0;
		top: 0;
		right: 0;
		bottom: 0;
		z-index: 103;
		background-color: rgba(0, 0, 0, 0.6);
		.bg{
			position: absolute;
			top: 0;
			left: 0;
			width: 100%;
			height: 100%;
		}
		.box{
			position: absolute;
			top: 50%;
			left: 50%;
			transform: translate(-50%,-50%);
			min-width: 590rpx;
			min-height: 338rpx;
			background: #FFFFFF;
			border-radius: 22rpx;
			padding: 90rpx 26rpx 50rpx;
			box-sizing: border-box;
			display: flex;
			flex-direction: column;
			.content-box{
				flex: 1;
				text-align: center;
				font-family: PingFangSC, PingFang SC;
				font-weight: 500;
				font-size: 34rpx;
				color: #222222;
			}
			.footer{
				padding-top: 20rpx;
				box-sizing: border-box;
				display: flex;
				gap: 0 20rpx;
				.item-cancel,.item-ok{
					flex: 1;
					height: 80rpx;
					border-radius: 40rpx;
					border: 1rpx solid #979797;
					transform: rotateZ(360deg);
					display: flex;
					align-items: center;
					justify-content: center;
					font-family: PingFangSC, PingFang SC;
					font-weight: 400;
					font-size: 34rpx;
				}
				.item-cancel{
					background: #FFFFFF;
					color: #000000;
				}
				.item-ok{
					background: linear-gradient( 90deg, #77C708 0%, #34B834 100%);
					color: #FFFFFF;
					border-color: transparent;
					&.ghost{
						border-color: #1FA71F;
						background: #FFFFFF;
						color: #1FA71F;
					}
				}
			}
			.close-btn{
				position: absolute;
				bottom: -174rpx;
				left: 50%;
				z-index: 2;
				transform: translateX(-50%);
				padding: 40rpx;
				box-sizing: border-box;
				.icon-close{
					width: 64rpx;
					height: 64rpx;
				}
			}
		}
	}
</style>

vue3版本:

<template>
	<view class="modal-container">
		<view class="bg" @tap="maskClose"></view>
		<view class="box">
			<view class="content-box">
				<slot></slot>
			</view>
			<view class="footer">
				<view v-if="cancelVisble" class="item-cancel" @tap="cancel">{{cancelText}}</view>
				<view :class="['item-ok',{'ghost':okGhost}]" @tap="ok">{{okText}}</view>
			</view>
			<view v-if="closable" class="close-btn" @tap="close">
				<image :src="config.imgs[0]" class="icon-close"></image>
			</view>
		</view>
	</view>
</template>

<script setup>
	defineOptions({ name: 'Modal' });
	const emit = defineEmits(['cancel','ok'])
	const props = defineProps({
		// 取消按钮文字
		cancelText:{
			type:String,
			default:"取消"
		},
		// 	取消按钮是否显示
		cancelVisble:{
			type:Boolean,
			default:true
		},
		// 确认按钮文字
		okText:{
			type:String,
			default:"确定"
		},
		// 幽灵属性,使按钮背景透明
		okGhost:{
			type:Boolean,
			default:false
		},
		// 点击蒙层是否允许关闭
		maskClosable:{
			type:Boolean,
			default:true
		},
		// 是否显示关闭按钮
		closable:{
			type:Boolean,
			default:true
		},
	})
	import {
		ref,
		reactive,
		computed,
		onMounted
	} from 'vue'
	const config = reactive({
		imgs:[
			'https://frontend-c.oss-cn-hangzhou.aliyuncs.com/wz-mini-program/v2/icons/close.png'
		]
	})
	
	const maskClose=()=>{
		if(props.maskClosable){
			// console.log("maskClose")
			emit("cancel")
		}
	}
	
	const close =()=>{
		// console.log("close")
		emit("cancel")
	}
	
	const cancel =()=>{
		// console.log("cancel")
		emit("cancel")
	}
	
	const ok =()=>{
		// console.log("ok")
		emit("ok")
	}
	
	
	onMounted(()=>{
		
	})
	
</script>

<style lang="scss" scoped>
	.modal-container{
		position: fixed;
		left: 0;
		top: 0;
		right: 0;
		bottom: 0;
		z-index: 103;
		background-color: rgba(0, 0, 0, 0.6);
		.bg{
			position: absolute;
			top: 0;
			left: 0;
			width: 100%;
			height: 100%;
		}
		.box{
			position: absolute;
			top: 50%;
			left: 50%;
			transform: translate(-50%,-50%);
			min-width: 590rpx;
			min-height: 338rpx;
			background: #FFFFFF;
			border-radius: 22rpx;
			padding: 90rpx 26rpx 50rpx;
			box-sizing: border-box;
			display: flex;
			flex-direction: column;
			.content-box{
				flex: 1;
				text-align: center;
				font-family: PingFangSC, PingFang SC;
				font-weight: 500;
				font-size: 34rpx;
				color: #222222;
			}
			.footer{
				padding-top: 20rpx;
				box-sizing: border-box;
				display: flex;
				gap: 0 20rpx;
				.item-cancel,.item-ok{
					flex: 1;
					height: 80rpx;
					border-radius: 40rpx;
					border: 1rpx solid #979797;
					transform: rotateZ(360deg);
					display: flex;
					align-items: center;
					justify-content: center;
					font-family: PingFangSC, PingFang SC;
					font-weight: 400;
					font-size: 34rpx;
				}
				.item-cancel{
					background: #FFFFFF;
					color: #000000;
				}
				.item-ok{
					background: linear-gradient( 90deg, #77C708 0%, #34B834 100%);
					color: #FFFFFF;
					border-color: transparent;
					&.ghost{
						border-color: #1FA71F;
						background: #FFFFFF;
						color: #1FA71F;
					}
				}
			}
			.close-btn{
				position: absolute;
				bottom: -174rpx;
				left: 50%;
				z-index: 2;
				transform: translateX(-50%);
				padding: 40rpx;
				box-sizing: border-box;
				.icon-close{
					width: 64rpx;
					height: 64rpx;
				}
			}
		}
	}
</style>

3、使用方法

import Modal from '@/components/modal/modal.vue';// 在所需*.vue中引用
<template>		
    <view>
        ****
        ****
        <!--自定义弹窗-->
		<modal v-if="isShowAdTip" :cancelVisbleMethod="true" @cancel="cancel" @ok="ok">确定添加要素点么?</modal>
	</view>
	
</template>
data(){
	return {
		isShowAdTip:false,
        ***
    }
},
          cancel(){// 自定义弹窗取消按钮事件
		   	//console.log("cancel回调")
		   	this.isShowAdTip = false;
		  },
		  ok(){// 自定义弹窗确定按钮事件
		   	//console.log("ok回调")
		   	this.isShowAdTip = false;
		   	// 传递信息新增要素点
		   	this.valueChangeSign.type= "ADDNEWFEATURE";
		   	this.valueChangeSign.flag = !that.valueChangeSign.flag;
		  },

<think>好的,用户想在uni-app中添加或配置自定义隐私协议,我需要根据提供的引用信息来解答这个问题。首先,查看引用内容,特别是引用[1]、[4]提到了隐私政策的配置方法。引用[4]提到在AndroidManifest.xml中添加meta-data节点,设置DCLOUD_PRIVACY_PROMPT为template,这可能与隐私弹窗模板有关。而引用[1]则指出必须在隐私政策中声明使用uni-app框架,需要添加特定的条款。此外,用户可能需要自定义隐私协议的内容,而不仅仅是使用默认的模板。 接下来,我需要分步骤说明如何在uni-app中配置。首先,原生工程的配置部分,修改AndroidManifest.xml,这属于原生层面的修改,用户可能需要使用HBuilderX进行原生配置。然后,隐私政策文档的内容需要包含必选条款,用户需要在自己的隐私政策中添加这些内容。另外,如果用户想自定义隐私协议的弹窗样式或逻辑,可能需要使用原生插件或修改原生代码,但uni-app本身可能没有直接提供这样的API,所以需要引导用户参考官方文档或社区方案。 同时,考虑到用户可能需要适配不同平台,比如iOS和Android,但引用[2]主要提到iOS的App ID配置,可能隐私政策的配置在iOS端也需要相应处理,但引用中没有详细说明,可能需要建议用户查阅苹果的隐私政策要求。 最后,用户可能需要测试隐私协议弹窗是否生效,确保应用商店上架时符合规定。需要提醒用户测试流程,并检查隐私政策内容是否正确包含uni-app的相关声明。</think>在 uni-app 中实现自定义隐私协议功能,需结合原生配置和框架特性,具体步骤如下: ### 第一步:配置原生工程隐私弹窗模式 1. 打开原生工程目录下的 `AndroidManifest.xml` 文件 2. 在 `<application>` 节点内添加模板配置: ```xml <meta-data android:name="DCLOUD_PRIVACY_PROMPT" android:value="template"/> ``` 该配置会启用系统默认隐私弹窗模板[^4] ### 第二步:自定义隐私政策内容 1. 在项目根目录创建 `hybrid/html/privacy.html` 文件 2. 编写自定义隐私协议内容(必须包含以下条款): ```html <!-- 必须声明框架使用 --> <p>本应用基于DCloud uni-app(5+ App/Wap2App)开发</p> <!-- 添加您的自定义协议内容 --> ``` ### 第三步:配置隐私政策弹窗触发 通过以下方式控制弹窗显示逻辑: ```javascript // 在App.vue的onLaunch中检测 plus.runtime.isAgreePrivacy(() => { console.log('用户已同意协议'); }, (e) => { // 显示自定义协议弹窗 uni.showModal({ title: '隐私协议', content: '请阅读并同意隐私政策', confirmText: '同意' }); }); ``` ### 第四步:应用商店适配 1. **Android**:需确保隐私政策文件包含DCloud框架声明[^1] 2. **iOS**:在Xcode工程中配置 `Info.plist` 添加隐私相关描述,与App Store审核要求保持一致[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值