美文网首页
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