美文网首页
vue3 自定义底部对话框

vue3 自定义底部对话框

作者: 硅谷干货 | 来源:发表于2022-03-10 08:56 被阅读0次

前言

移动端开发中,类似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>

注意:创建文件部分直接拷贝可用,样式稍作修改即可,希望能帮到你

点赞加关注,永远不迷路

相关文章

网友评论

      本文标题:vue3 自定义底部对话框

      本文链接:https://www.haomeiwen.com/subject/jsbtdrtx.html