vue3 - 自定义弹框组件

news2025/3/2 2:03:39

在这里插入图片描述

写了一个弹框组件
<template>
  <transition name="modal-fade">
    <div v-if="showFlag" class="myModal">
      <div class="content">
        <div class="topBox">
          <div class="leftTitle">
            <span>{{ title }}</span>
          </div>
          <div class="rightClose" @click="cancelModal"><CloseOutlined /></div>
        </div>
        <slot name="content"></slot>
      </div>
    </div>
  </transition>
</template>

<script setup lang="ts">
import { ref, toRefs } from 'vue'

const props = defineProps({
  title: {
    type: String,
    default: '',
  },
})

const { title } = toRefs(props)

// 是否开启弹框
let showFlag = ref(false)

// 开启
const showModal = () => {
  showFlag.value = true
}

// 关闭
const cancelModal = () => {
  showFlag.value = false
}

defineExpose({
  showModal,
  cancelModal,
})
</script>

<style lang="less" scoped>
// 这个动画是,打开弹框时,有一个缓慢打开的效果
@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

// 打开弹框时给它一个上下抖动的效果
@keyframes shake {
  0% { transform: translateY(0); }
  25% { transform: translateY(-10px); }
  50% { transform: translateY(0); }
  75% { transform: translateY(10px); }
  100% { transform: translateY(0); }
}

.myModal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.4);
  z-index: 100;

  animation: fadeIn 0.5s;
  // animation: fadeIn 0.5s, shake 0.5s;

  .content {
    position: absolute;
    left: 50%;
    top: 30%;
    transform: translate(-50%, -50%);
    background: #ffffff;
    width: 500px;
    padding: 10px;

    .topBox {
      display: flex;
      height: 30px;
      border-bottom: 1px solid #f0f0f0;
      padding: 0 10px 0 0;
      margin-bottom: 20px;
      cursor: pointer;

      .leftTitle {
        flex: 1;
        text-align: left;
        color: rgba(0, 0, 0, 0.8);
        font-weight: 600;
        font-size: 16px;
      }

      .rightClose {
        flex: 1;
        text-align: right;
      }
    }
  }
}

// start - 效果为:关闭时,有一个缓慢消失的效果
.modal-fade-enter-active, .modal-fade-leave-active {
  transition: opacity 0.5s;
}
.modal-fade-enter, .modal-fade-leave-to {
  opacity: 0;
}
// end - 效果为:关闭时,有一个缓慢消失的效果
</style>


使用它
<template>
  <MyModal ref="myModal" :title="title">
    <template #content>
      <div style="display: grid; place-items: center">
        <a-form ref="loginForm" :model="formState" :label-col="labelCol" style="width: 360px">
          <a-form-item has-feedback name="userName">
            <a-input v-model:value="formState.phone" placeholder="请输入手机号" autocomplete="off">
              <template #prefix><UserOutlined style="color: rgba(0, 0, 0, 0.25)" /></template>
            </a-input>
          </a-form-item>

          <a-form-item has-feedback name="code">
            <a-input
              v-model:value="formState.code"
              placeholder="验证码"
              autocomplete="off"
              style="width: 240px"
            >
              <template #prefix><MailOutlined style="color: rgba(0, 0, 0, 0.25)" /></template>
            </a-input>
            <a-button
              :disabled="myState.smsSendFlag"
              v-text="(!myState.smsSendFlag && '获取验证码') || `${myState.time} s`"
              @click="getSms"
              style="margin-left: 15px"
              type="primary"
            ></a-button>
          </a-form-item>

          <a-form-item style="text-align: center">
            <a-button style="width: 360px" type="primary" block @click="handleSubmit">
              登录
            </a-button>
          </a-form-item>
        </a-form>
      </div>
    </template>
  </MyModal>
</template>

<script setup lang="ts">
import { ref } from 'vue'

import * as accountApi from '@/api/account'

import MyModal from '@/components/MyModal/MyModal.vue'
import { message } from 'ant-design-vue'

const myModal = ref()

const showModal = () => {
  myModal.value?.showModal()
}

defineExpose({
  showModal,
})

let title = ref('x管家登陆')

const myState = reactive({
  smsSendFlag: false,
  time: 60,
})

let labelCol = { span: 4 }
interface formState {
  phone: string | number
  code: string | number
}
const formState = ref<formState>({
  phone: '',
  code: '',
})

// 获取验证码
const getSms = async () => {
  let params = {
    phone: formState.value.phone,
  }
  if (params['phone'] == '') {
    message.error(`手机号不能为空~`)
    return
  }
  const hide = message.loading('验证码发送中..', 0)
  try {
    let { state, message: msg } = await accountApi.idleSendSms(params)
    if (state === 200) {
      myState.smsSendFlag = true
      const interval = setInterval(() => {
        if (myState.time-- <= 0) {
          myState.time = 60
          myState.smsSendFlag = false
          clearInterval(interval)
        }
      }, 1000)
    } else {
      message.error(msg)
    }
  } catch (error) {
    message.error('网络请求连接失败~')
  }
  setTimeout(hide, 1)
}

// 登录
const handleSubmit = async () => {
  let params = {
    phone: formState.value.phone,
    code: formState.value.code,
  }
  try {
    const { state, message: msg, token } = await accountApi.idleLogin(params)
    if (state === 200) {
      message.success('登录成功~')
      myModal.value?.cancelModal()
    } else {
      message.error(msg)
    }
  } catch (error) {
    message.error('网络请求发送失败~')
  }
}
</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1382215.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

爬虫—抓取表情党热门栏目名称及链接

爬虫—抓取表情党热门栏目名称及链接 表情党网址&#xff1a;https://qq.yh31.com/ 目标&#xff1a;抓取表情党主页的热门栏目名称及对应的链接&#xff0c;如下图所示&#xff1a; 按F12&#xff08;谷歌浏览器&#xff09;&#xff0c;进入开发者工具模式&#xff0c;进行…

机器学习数据处理

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

【图形学】探秘图形学奥秘:DDA与Bresenham算法的解密与实战

​&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《图形学 | 图像解码》⏰诗赋清音&#xff1a;云生高巅梦远游&#xff0c; 星光点缀碧海愁。 山川深邃情难晤&#xff0c; 剑气凌云志自修。 ​ 目录 &#x1f30c;1. 初识模式识别…

28 星际旋转

效果演示 实现了一个太阳系动画&#xff0c;其中包括了地球、火星、金星、土星、水星、天王星、海王星以及火卫二号等行星的动画效果。太阳系的行星都被放在一个固定的容器中&#xff0c;并使用CSS动画来实现旋转和移动的效果。当太阳系的行星绕着太阳运行时&#xff0c;它们会…

鸿蒙开发-UI-组件-状态管理

鸿蒙开发-序言 鸿蒙开发-工具 鸿蒙开发-初体验 鸿蒙开发-运行机制 鸿蒙开发-运行机制-Stage模型 鸿蒙开发-UI 鸿蒙开发-UI-组件 文章目录 前言 一、什么是状态管理 二、管理组件拥有的状态 1.组件内状态 State装饰器 2.父子组价单向同步 Prop装饰器 3.父子双向同步 Link装…

Gitlab中的CICD的使用方法

一、CI/CD执行机制 二、离线安装gitlab-runner 下载相应版本的gitlab-runner &#xff08;下载地址&#xff1a;https://packages.gitlab.com/runner/gitlab-runner&#xff09; dpkg -i gitlab-runner_12.8.0_amd64.debgitlab-runner register第3步中需要的信息可从下图所示…

mysql关于创建表的小试题

目录 例题&#xff1a; 解题思路及步骤&#xff1a; 实验步骤&#xff1a; 步骤一&#xff1a;创建数据库 步骤二&#xff1a;创建表 步骤三&#xff1a;插入数据 例题&#xff1a; 1、创建一个英雄表(hero)&#xff0c;管于四大名著的主键 nam…

翻译: Streamlit从入门到精通 基础控件 一

这个关于Streamlit的教程旨在帮助数据科学家或机器学习工程师&#xff0c;他们不是网络开发者&#xff0c;也不想花费数周时间学习使用这些框架来构建网络应用程序。 1. 什么是Streamlit&#xff1f; Streamlit是一个免费且开源的框架&#xff0c;用于快速构建和共享美观的机器…

基于Go框架,Cloudreve个人免费开源网盘系统源码,支持云存储(七牛、阿里云OSS、腾讯云COS、又拍云、OneDrive)

源码介绍 在数字化时代&#xff0c;我们经常需要存储、分享大量的文件&#xff0c;如照片、视频、文档等。然而&#xff0c;许多商业网盘服务却存在限速、收费等问题&#xff0c;给用户带来诸多不便。现在&#xff0c;我们为您推荐一款免费开源的网盘系统——Cloudreve。 Clo…

【PACS Web系统】全网首发JAVA开发PACS医疗影像工作站

目录 业务分析&#xff1a; 市场前景&#xff1a; Web版相对单机版优势&#xff1a; 主干功能&#xff1a; RBAC用户权限管理、服务监控、字典维护、通知公告等基础模块&#xff1b; 手动上传Dicom文件/文件夹&#xff0c;及接收Dicom服务器的Dicom文件集功能&#xff1b…

Sqoop与其他数据采集工具的比较分析

比较Sqoop与其他数据采集工具是一个重要的话题&#xff0c;因为不同的工具在不同的情况下可能更适合。在本博客文章中&#xff0c;将深入比较Sqoop与其他数据采集工具&#xff0c;提供详细的示例代码和全面的内容&#xff0c;以帮助大家更好地了解它们之间的差异和优劣势。 Sq…

LLVM系列(1): 在微软Visual Studio下编译LLVM

参考链接&#xff1a; Getting Started with the LLVM System using Microsoft Visual Studio — LLVM 18.0.0git documentation 1.安装visualstudio&#xff0c;版本需要大于vs2019 本机环境已安装visual studio2022&#xff0c;省略 2安装Makefile&#xff0c;版本需要大…

操作系统详解(5)——信号(Signal)

系列文章&#xff1a; 操作系统详解(1)——操作系统的作用 操作系统详解(2)——异常处理(Exception) 操作系统详解(3)——进程、并发和并行 操作系统详解(4)——进程控制(fork, waitpid, sleep, execve) 文章目录 概述信号的种类Hardware EventsSoftware Events 信号的原理信号…

PostgreSQL认证考试PGCA、PGCE、PGCM

PostgreSQL认证考试PGCA、PGCE、PGCM 【重点&#xff01;重点&#xff01;重点&#xff01;】PGCA、PGCE、PGCM 直通车快速下正&#xff0c;省心省力&#xff0c;每2个月一次考试 PGCE考试通知 &#xff08;2024&#xff09; 一、考试概览 &#xff08;一&#xff09; 报名要…

【C++】wxWidgets库实现窗体程序

一、安装wxWidgets库 在Debian系统上使用wxWidgets库来创建一个基本的窗体程序&#xff0c;首先需要确保已经安装了wxWidgets相关的库和开发工具。下面是安装wxWidgets的步骤&#xff1a; 打开终端&#xff0c;使用下述命令安装wxWidgets库及其开发文件&#xff1a; sudo ap…

恒通未来-大数据传输中的WDM解决方案

DWDM的出现是光纤传输技术发展中最新的重要现象之一。本教程将介绍DWDM技术的基本原理&#xff0c;如组件、DWDM系统中使用的光放大器等。 组件和操作&#xff1a; DWDM是光传输网络中的一种核心技术。DWDM的基本组件可以根据其在系统中的位置进行分类。在发射方面&#xff0…

hardware simulation——框架搭建

目录 引子 代码风格约束 代码结构和模板 引子 前几天有人拿个word文档&#xff0c;问我怎么实现&#xff0c;概括一下就是用c实现数码管显示。 但是咱们肯定不做这么简单这么点&#xff0c;我打算做个开源的项目&#xff0c;可以一直更新底层软件库&#xff0c;和上层显示库…

在centos系统安装mqtt

在CentOS系统上安装MQTT&#xff0c;通常意味着要安装一个MQTT代理&#xff08;broker&#xff09;&#xff0c;比如Mosquitto。下面是在CentOS上安装Mosquitto的步骤&#xff1a; 添加EPEL仓库&#xff1a; 由于Mosquitto可能不在CentOS默认的Yum仓库中&#xff0c;你可能需要…

关于 setData 同步异步的问题

小程序官方文档中的回答解释: 所以大概意思就是: 1.setData在逻辑层的操作是同步&#xff0c;因此this.data中的相关数据会立即更新,比如下面的例子: const a 1 this.setData({b: a ? a : , }) console.log(that.data.b) // 1 2. setData在视图层的操作是异步&#xff0c;…

八爪鱼拉拉手

欢迎来到程序小院 八爪鱼拉拉手 玩法&#xff1a;点击鼠标左键拖动移动八爪鱼&#xff0c;当他的手很忙的时候他会很高兴&#xff0c; 不同关卡不同的八爪鱼的位置摆放&#xff0c;快去闯关吧^^。开始游戏https://www.ormcc.com/play/gameStart/248 html <div id"gam…