前言
移动端开发中,类似Android原生 AlertDialog对话框和iOS原生UIAlertController对话框场景经常遇到,今天我们来实现一个类似iOS中的UIActionSheet底部对话框。
实现效果
image.png创建MyDialog.vue文件
<template>
<teleport to="#app">
<transition name="dialog">
<div class="notice-box" v-if="visible">
<div class="modal-dialog">
<div class="title">{{ agreement.title }}</div>
<div class="details">
<p class="plain-text">
<span>{{ agreement.content }}</span>
<span
class="blue-text cursor-pointer"
@click.stop="handlerPetalPrivacy"
>{{ agreement.appPrivacy }}</span>。
</p>
</div>
<div class="bottom-box">
<div class="operate-btn cursor-pointer" @click="handlerCancel">取消</div>
<div class="divider"></div>
<div class="operate-btn stop-btn cursor-pointer" @click="handlerStop">停止</div>
</div>
</div>
</div>
</transition>
</teleport>
</template>
<script lang="ts" setup>
import { computed } from "vue";
const props = defineProps(['modelValue'])
const emits = defineEmits(['change', 'update:modelValue'])
const agreement = {
title: "确定关闭通知",
content:
"您正在终止与我们的用户协议。除非有其他继续处理的法律依据,否则所有为向您提供App服务而处理的数据都将被删除。更多信息,请参阅关于",
appPrivacy: "App隐私的声明",
petalPrivacyUrl:
"https://www.baidu.com/",
};
const visible = computed(() => {
return props.modelValue
})
// 隐私声明
function handlerPetalPrivacy() {
location.href = 'https://www.baidu.com'
}
// 取消
function handlerCancel() {
changeVisible(false);
}
// 停止,清除快应用Petal出行数据并退出快应用
function handlerStop() {
changeVisible(false);
}
// 开关点击后的状态传给v-model
const changeVisible = (val: boolean) => {
emits("update:modelValue", val);
emits("change", val);
};
</script>
<style lang="scss" scoped>
.notice-box {
top: 0;
left: 0;
height: 100%;
width: 100%;
background: rgba(0, 0, 0, 0.44);
position: fixed;
z-index: 5;
.modal-dialog {
padding: 13px 24px;
border-radius: 24px;
background: #ececed;
position: absolute;
bottom: 0;
left: 50%;
width: 93%;
transform: translate(-50%, -12px);
display: flex;
flex-direction: column;
font-family: HuaweiSans-Medium;
.title {
font-family: HuaweiSans-Medium;
font-size: 20px;
color: #000000;
text-align: left;
line-height: 28px;
font-weight: 500;
}
.details {
margin-top: 20px;
font-family: HuaweiSans-Medium;
font-size: 16px;
color: #000000;
font-weight: 400;
text-align: left;
.plain-text {
margin: 0px;
color: #000000;
.blue-text {
color: #0a59f7;
}
}
}
.bottom-box {
display: flex;
justify-content: space-around;
align-items: center;
margin: 15px 0 20px;
.operate-btn {
text-align: center;
font-family: HuaweiSans-Medium;
font-size: 16px;
color: #0a59f7;
font-weight: 500;
padding: 3px;
}
.stop-btn {
color: #e84026;
}
.divider {
width: 1px;
height: 22px;
background-color: #c7c8c9;
}
}
}
}
/* 命名过渡动画 */
.dialog-enter-active,
.dialog-leave-active {
transition: all 0.3s ease;
}
.dialog-enter-from,
.dialog-leave-to {
opacity: 0;
}
</style>
项目中使用
<template>
<my-dialog v-model="visible"/>
</template>
<script setup lang="ts">
import { ref } from "vue";
const visible = ref(visible);
import MyDialog from "@/views/user/components/MyDialog.vue";
</script>
注意:创建文件部分直接拷贝可用,样式稍作修改即可,希望能帮到你
点赞加关注,永远不迷路
网友评论