Vue3信息提示(Modal)

Vue2信息提示(Modal)

可自定义设置以下属性:

  • 标题描述(title),类型:string,默认 'Title'

  • 内容描述(content),类型:string,默认 'content'

  • 提示框宽度(width),类型:number,默认 420px

  • 取消按钮文字(cancelText),类型:string,默认 '取消'

  • 确认按钮文字(okText),类型:string,默认 '确认'

  • 通知按钮文字(noticeText),类型:string,默认 '知道了'

  • 提示框类型(mode),类型:string,默认 'confirm',可选 'info'(确认提示框:confirm 信息提示框:info)

  • 提示框类型(type),类型:string,默认 'confirm',可选(mode: confirm时 'confirm' 'delete'  mode: info时 'info' 'success' 'error' 'warn')

  • 是否水平垂直居中(center),类型:boolean,默认 true,(false时是固定高度水平居中)

  • 固定高度水平居中时,距顶部高度(top),类型:number, 默认 100px

  • 加载中(loading),类型:boolean,默认 false

  • 提示框是否可见(visible),类型:boolean,默认 false

一共有两种模式,共六种展示效果,弹窗随内容自适应增加高度,同时支持对弹窗位置进行设置:①水平垂直居中②高度固定水平居中

效果如下图:(整体样式模仿ant-design-vue Modal,同时阴影覆盖浏览器窗口)

mode: 'confirm' type: 'confirm'

mode: 'confirm' type: 'delete'

mode: 'info' type: 'info'

mode: 'info' type: 'success'

mode: 'info' type: 'error'

 mode: 'info' type: 'warn'

 ①创建信息提示框组件Modal.vue:

<script setup lang="ts">
defineProps({ // 运行时声明
  title: { // 标题描述
    type: String,
    default: 'Title'
  },
  content: { // 内容描述
    type: String,
    default: 'Content'
  },
  width: { // 提示框宽度
    type: Number,
    default: 420,
  },
  cancelText: { // 取消按钮文字
    type: String,
    default: '取消'
  },
  okText: { // 确认按钮文字
    type: String,
    default: '确定'
  },
  noticeText: { // 通知按钮文字
    type: String,
    default: '知道了'
  },
  mode: { // 确认提示框:confirm  信息提示框:info
    type: String,
    default: 'confirm'
  },
  type: { // confirm mode: 'confirm', 'delete'   info mode: 'info', 'success', 'error', 'warn'
    type: String,
    default: 'confirm'
  },
  center: { // 水平垂直居中:true  固定高度水平居中:false
    type: Boolean,
    default: true
  },
  top: { // 固定高度水平居中时,距顶部高度
    type: Number,
    default: 100
  },
  loading: { // 加载中...
    type: Boolean,
    default: false
  },
  visible: { // 提示框是否可见
    type: Boolean,
    default: false
  }
})

const emits = defineEmits(['cancel', 'ok'])
function onBlur () {
  emits('cancel')
}
function onCancel () {
  emits('cancel')
}
function onConfirm () {
  emits('ok')
}
</script>
<template>
  <Transition>
    <div class="m-modal-mask" v-show="visible" @click.self="onBlur">
      <div :class="['m-modal', center ? 'relative-hv-center' : 'top-center']" :style="`width: ${width}px; top: ${!center ? top + 'px':'50%'};`">
        <div :class="['m-modal-body', {'loading':loading}]">
          <div class="m-spin-dot" v-show="loading">
            <span class="u-dot-item"></span>
            <span class="u-dot-item"></span>
            <span class="u-dot-item"></span>
            <span class="u-dot-item"></span>
          </div>
          <div class="m-body">
            <div class="m-title">
              <template v-if="mode==='confirm'">
                <svg focusable="false" class="u-icon confirm" data-icon="exclamation-circle" aria-hidden="true" viewBox="64 64 896 896"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"></path><path d="M464 688a48 48 0 1096 0 48 48 0 10-96 0zm24-112h48c4.4 0 8-3.6 8-8V296c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v272c0 4.4 3.6 8 8 8z"></path></svg>
              </template>
              <template v-if="mode==='info'">
                <svg focusable="false" class="u-icon info" v-if="type==='info'" data-icon="info-circle" aria-hidden="true" viewBox="64 64 896 896"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm32 664c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V456c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272zm-32-344a48.01 48.01 0 010-96 48.01 48.01 0 010 96z"></path></svg>
                <svg focusable="false" class="u-icon success" v-if="type==='success'" data-icon="check-circle" aria-hidden="true" viewBox="64 64 896 896"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 01-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z"></path></svg>
                <svg focusable="false" class="u-icon error" v-if="type==='error'" data-icon="close-circle" aria-hidden="true" viewBox="64 64 896 896"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 01-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"></path></svg>
                <svg focusable="false" class="u-icon warn" v-if="type==='warn'" data-icon="exclamation-circle" aria-hidden="true" viewBox="64 64 896 896"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 010-96 48.01 48.01 0 010 96z"></path></svg>
              </template>
              <div class="u-title">{{ title }}</div>
            </div>
            <div class="u-content">{{ content }}</div>
          </div>
          <div class="m-btns">
            <template v-if="mode==='confirm'">
              <button class="u-cancel" @click="onCancel">{{ cancelText }}</button>
              <button class="u-confirm primary" @click="onConfirm" v-if="type==='confirm'">{{ okText }}</button>
              <button class="u-confirm delete" @click="onConfirm" v-if="type==='delete'">{{ okText }}</button>
            </template>
            <template v-if="mode==='info'">
              <button class="u-confirm primary" @click="onConfirm">{{ noticeText }}</button>
            </template>
          </div>
        </div>
      </div>
    </div>
  </Transition>
</template>
<style lang="less" scoped>
.v-enter-active, .v-leave-active {
  transition: opacity 0.3s ease;
}
.v-enter-from, .v-leave-to {
  opacity: 0;
}
.flex-hv-center { // 水平垂直居中方法①:弹性布局,随内容增大高度,并自适应水平垂直居中
  display: flex;
  justify-content: center;
  align-items: center;
}
.relative-hv-center { // 水平垂直居中方法②:相对定位,随内容增大高度,并自适应水平垂直居中
  position: relative;
  top: 50%;
  transform: translateY(-50%);
}
.top-center { // 相对定位,固定高度,始终距离视图顶端100px
  position: relative;
  // top: 100px;
}
.m-modal-mask {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1000;
  background: rgba(0,0,0,0.45);
  .m-modal {
    width: 420px;
    margin: 0 auto;
    color: rgba(0, 0, 0, 0.88);
    font-size: 14px;
    line-height: 1.5;
    .m-modal-body {
      position: relative;
      word-wrap: break-word;
      padding: 20px 24px;
      background: #fff;
      border-radius: 8px;
      box-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
      .m-spin-dot { // 绝对定位,并设置水平垂直居中
        position: absolute;
        display: inline-block;
        right: 0;
        left: 0;
        top: 0;
        bottom: 0;
        margin: auto;
        width: 20px;
        height: 20px;
        transform: rotate(45deg);
        -ms-transform: rotate(45deg); /* Internet Explorer */
        -moz-transform: rotate(45deg); /* Firefox */
        -webkit-transform: rotate(45deg); /* Safari 和 Chrome */
        -o-transform: rotate(45deg); /* Opera */
        animation: rotate 1.2s linear infinite;
        -webkit-animation: rotate 1.2s linear infinite;
        @keyframes rotate {
          100% {transform: rotate(405deg);}
        }
        .u-dot-item { // 单个圆点样式
          position: absolute;
          width: 8px;
          height: 8px;
          background: @themeColor;
          border-radius: 50%;
          opacity: .3;
          animation: spinMove 1s linear infinite alternate;
          -webkit-animation: spinMove 1s linear infinite alternate;
          @keyframes spinMove {
            100% {opacity: 1;}
          }
        }
        .u-dot-item:first-child {
          top: 0;
          left: 0;
        }
        .u-dot-item:nth-child(2) {
          top: 0;
          right: 0;
          animation-delay: .4s;
          -webkit-animation-delay: .4s;
        }
        .u-dot-item:nth-child(3) {
          bottom: 0;
          right: 0;
          animation-delay: .8s;
          -webkit-animation-delay: .8s;
        }
        .u-dot-item:last-child {
          bottom: 0;
          left: 0;
          animation-delay: 1.2s;
          -webkit-animation-delay: 1.2s;
        }
      }
      .m-body {
        .m-title {
          width: 100%;
          .u-icon {
            display: inline-block;
            margin-right: 12px;
            margin-top: 1px;
            width: 22px;
            height: 22px;
            font-size: 16px;
            font-weight: bold;
            vertical-align: top;
          }
          .confirm {
            fill: #faad14;
          }
          .info {
            fill: @themeColor;
          }
          .success {
            fill: #52c41a;
          }
          .error {
            fill: #ff4d4f;
          }
          .warn {
            fill: #faad14;
          }
          .u-title {
            display: inline-block;
            vertical-align: top;
            font-size: 16px;
            font-weight: 600;
            max-width: calc(100% - 34px);
          }
        }
        .u-content {
          margin-left: 34px;
          margin-top: 8px;
          font-size: 14px;
          max-width: calc(100% - 34px);
        }
      }
      .m-btns {
        margin-top: 24px;
        text-align: right;
        .u-cancel {
          height: 32px;
          line-height: 32px;
          padding: 0 15px;
          font-size: 14px;
          border-radius: 4px;
          color: rgba(0,0,0,.65);
          background: #fff;
          border: 1px solid #d9d9d9;
          cursor: pointer;
          transition: all .3s cubic-bezier(.645,.045,.355,1);
          &:hover {
            color: fade(@themeColor, 80%);
            border-color: fade(@themeColor, 80%);
          }
          &:focus {
            color: shade(@themeColor, 12%);
            border-color: shade(@themeColor, 12%);
          }
        }
        .u-confirm {
          margin-left: 8px;
          height: 32px;
          line-height: 32px;
          padding: 0 15px;
          font-size: 14px;
          border-radius: 4px;
          color: #fff;
          transition: all .3s cubic-bezier(.645,.045,.355,1);
          cursor: pointer;
        }
        .primary {
          background: @themeColor;
          border: 1px solid @themeColor;
          &:hover {
            background: fade(@themeColor, 80%);
            border-color: fade(@themeColor, 80%);
          }
          &:focus {
            background: shade(@themeColor, 12%);
            border-color: shade(@themeColor, 12%);
          }
        }
        .delete {
          background: #ff4d4f;
          border: 1px solid #ff4d4f;
          &:hover {
            background-color: #ff7875;
            border-color: #ff7875;
          }
          &:focus {
            background-color: #d9363e;
            border-color: #d9363e;
          }
        }
      }
    }
    .loading { // 加载过程背景虚化
      background: rgb(248, 248, 248);
      pointer-events: none; // 屏蔽鼠标事件
    }
  }
}
</style>

②在要使用的页面引入:

<script setup lang="ts">
import { Modal } from './Modal.vue'
import { ref } from 'vue'
import { rafTimeout } from '../../packages'

const center = ref(true)
const loading = ref(false)
const visible = ref(false)
const title = ref('')
const content = ref('Content of the modal ...')
const mode = ref('confirm')
const type = ref('delete')
function showConfirmModal (info: string) {
  mode.value = 'confirm'
  type.value = 'confirm'
  title.value = 'Do you Want to submit these items ?'
  content.value = info
  center.value = true
  visible.value = true
}
function showDeleteModal (info: string) {
  mode.value = 'confirm'
  type.value = 'delete'
  title.value = 'Do you Want to delete these items ?'
  content.value = info
  center.value = true
  visible.value = true
}
function showInfoModal (info: string) {
  mode.value = 'info'
  type.value = 'info'
  title.value = 'Do you See these items ?'
  content.value = info
  center.value = true
  visible.value = true
}
function showSuccessModal (info: string) {
  mode.value = 'info'
  type.value = 'success'
  title.value = 'Do you See these items ?'
  content.value = info
  center.value = true
  visible.value = true
}
function showErrorModal (info: string) {
  mode.value = 'info'
  type.value = 'error'
  title.value = 'Do you See these items ?'
  content.value = info
  center.value = true
  visible.value = true
}
function showWarnModal (info: string) {
  mode.value = 'info'
  type.value = 'warn'
  title.value = 'Do you See these items ?'
  content.value = info
  center.value = true
  visible.value = true
}
function showFixModal (info: string) {
  mode.value = 'info'
  type.value = 'success'
  title.value = 'Do you See these items ?'
  center.value = false
  content.value = info
  visible.value = true
}
function onCancel () { // “取消”按钮回调
  visible.value = false
}
function onConfirm () { // “确定”,“知道了”按钮回调
  loading.value = true // 开启加载状态
  rafTimeout(() => {
    visible.value = false
    loading.value = false
  }, 500)
}

</script>
<template>
  <div>
    <h2 class="mb10">Modal 信息提示基本使用</h2>
    <Button class="mr30" @click="showConfirmModal('Some descriptions ...')">提交确认</Button>
    <Button class="mr30" @click="showDeleteModal('Some descriptions ...')">删除确认</Button>
    <Button class="mr30" @click="showInfoModal('Some descriptions ...')">Info</Button>
    <Button class="mr30" @click="showSuccessModal('Some descriptions ...')">Success</Button>
    <Button class="mr30" @click="showErrorModal('Some descriptions ...')">Error</Button>
    <Button class="mr30" @click="showWarnModal('Some descriptions ...')">Warn</Button>
    <Button class="mr30" @click="showFixModal('Some descriptions ...')">高度固定</Button>
    <Modal
      :title="title"
      :content="content"
      :width="416"
      :top="200"
      cancelText="取消"
      okText="确认"
      noticeText="知道了"
      :mode="mode"
      :type="type"
      :center="center"
      :loading="loading"
      @cancel="onCancel"
      @ok="onConfirm"
      :visible="visible"
    />
  </div>
</template>
<style lang="less" scoped>
</style>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

盲盒经济下与社交电商结合,打造电商卖货新模式

如今&#xff0c;盲盒经济正在从线下延伸到线上&#xff0c;从潮流玩具扩展到美妆、食品、服装、数码等领域&#xff0c;形成了一种新的电商生态。 什么是盲盒电商&#xff1f; 盲盒电商是一种电商行业的营销模式&#xff0c;通过发起盲盒活动或拆盲盒&#xff0c;让参与者不…

MongoDB 查询文档(3)

我们之前讲解过&#xff0c;查询文档的语法&#xff1a; db.collection.find(query, projection, options) 其中 query 代表的是查询过滤器&#xff0c;projection 代表的是文档返回的字段&#xff0c;options 代表的是用于查询的其他选项&#xff1b; 我们已经对query进行了…

Ubuntu16.04虚拟机下安装Qt5.10.0

首先安装虚拟机Vmware,具体参见: Win10安装Vmware+Ubuntu16.04_芯片-嵌入式的博客-CSDN博客 安装完成后,下载qt-opensource-linux-x64-5.10.0.run,使用U盘来实现win10和ubuntu虚拟机之间的文件传输,cp到一个目录后,sudo ./qt-opensource-linux-x64-5.10.0.run进行运行,…

I/O多路转接之select

初识select 系统提供select函数来实现多路复用输入/输出模型.* select系统调用是用来让我们的程序监视多个文件描述符的状态变化的; * 程序会停在select这里等待&#xff0c;直到被监视的文件描述符有一个或多个发生了状态改变;select函数原型 select的函数原型如下: #include …

SpringCloud 使用sentinel

一、添加依赖 <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> 二、配置文件配置地址 spring:cloud:sentinel:transport:dashboard: localhost:8080三…

【CSS】课程网站 网格商品展示 模块制作 ① ( 网格商品展示模块盒子模型测量及样式 | 顶部文本标题盒子测量及样式 | 代码示例 )

文章目录一、网格商品展示模块盒子模型测量及样式1、盒子尺寸测量2、标题盒子尺寸测量和样式3、左侧文本盒子尺寸测量和样式4、右侧文本盒子尺寸测量和样式二、顶部文本标题盒子代码示例1、HTML 标签结构2、CSS 样式3、展示效果绘制矩形框中的部分 : 一、网格商品展示模块盒子…

【服务器数据恢复】NTFS分区被格式化如何恢复数据?

服务器数据恢复环境&故障&#xff1a; 误操作格式化服务器RAID5磁盘阵列下的分区&#xff08;NTFS文件系统&#xff09;。 服务器数据恢复过程&#xff1a; 1、将故障服务器连接到北亚企安备份服务器上&#xff0c;将故障服务器的所有硬盘设置为脱机状态&#xff0c;然后以…

什么是中间件?

一、什么是中间件&#xff1f; 1、百度百科 中间件是介于应用系统和系统软件之间的一类软件&#xff0c;它使用系统软件所提供的基础服务&#xff08;功能&#xff09;&#xff0c;衔接网络上应用系统的各个部分或不同的应用&#xff0c;能够达到资源共享、功能共享的目的。目…

手写简易 Spring(二)

文章目录手写简易 Spring&#xff08;二&#xff09;1. 扩展 BeanFactory 接口2. 实现资源加载器&#xff0c;从 Spring.xml 解析和注册 Bean 对象1. 核心实现类 XmlBeanDefinitionReader3. 实现应用上下文&#xff0c;自动识别、资源加载、扩展机制1. 应用上下文2. 核心实现类…

java基础之抽象类与接口

文章目录1.抽象方法和抽象类2.抽象类的作用3.接口4.接口和抽象类的异同5.面向接口编程1.抽象方法和抽象类 抽象方法和抽象类必须使用abstract修饰符来定义&#xff0c;有抽象方法的类只能被定义成抽象类&#xff0c;抽象类里可以没有抽象方法。 抽象类必须使用abstract修饰符来…

【Redis学习】Redis入门概述

Redis是什么 Redis:REmote Dictionary Server(远程字典服务器) 官网介绍&#xff1a;The open source, in-memory data store used by millions of developers as a database, cache, streaming engine, and message broker.&#xff08;被数百万开发人员用作数据库、缓存、流…

在云服务部署前后端以及上传数据库

1.上传数据库(sql文件) 首先建立一个目录&#xff0c;用于存放要部署的sql文件&#xff0c;然后在此目录中进入mysql 进入后建立一个数据库&#xff0c;create database 数据库名 完成后&#xff0c;通过select * from 表名可以查到数据说明导入成功。 2.部署Maven后端 将Ma…

【预处理和程序环境】

预处理和程序环境一、程序的翻译环境和执行环境二、详解编译链接三、#define1. #define定义标识符2. #define定义宏3. #define的替换规则4. #和##4.1 #的使用4.2 ##的使用四、宏和函数对比五、条件编译一、程序的翻译环境和执行环境 我们的代码写完后称为源代码&#xff0c;源…

如何正确配置美国网络服务器?

在使用美国网络服务器时&#xff0c;充分注意其配置对于确保服务器和网络的性能、稳定性和安全性至关重要。网络服务器配置是指设置和配置网络服务器的硬件和软件以使其启动和运行的过程。它涉及多个步骤&#xff0c;包括配置操作系统、网络协议、安全设置、用户访问、共享资源…

linux驱动开发 - 01_字符设备驱动开发

文章目录字符设备驱动开发1. 字符设备驱动简介2 字符设备驱动开发步骤2.1 驱动模块的加载和卸载2.2 字符设备注册与注销2.3 实现设备的具体操作函数2.4 添加 LICENSE 和作者信息3 Linux 设备号3.1 设备号的组成3.2 设备号的分配4 chrdevbase 字符设备驱动开发实验4.1 实验程序编…

QT 之基础(一) 详解UI文件设计与运行机制

一、项目文件组成 1.1 创建一个项目文件 建立好项目如下 &#xff08;1&#xff09;项目组织文件【untitled.pro】 存储项目设置文件 QT core gui //表示项目中添加core gui模块 greaterThan(QT_MAJOR_VERSION, 4): QT widgets //条件执行语句&#xf…

【消息队列】聊一下如何避免消息的重复消费

什么是重复消费 一条消息在传输过程中&#xff0c;为了保证消息的不丢失&#xff0c;可能会多少量的消息进行重试&#xff0c;这样就可能导致Broker接受到的消息出现重复&#xff0c;如果说下游系统没有针对业务上的处理&#xff0c;那么可能导致同一笔借款或者支付订单出现重…

【Java多线程基础】Java线程的状态及主要转换方法

借鉴文献&#xff1a; 深入浅出Java多线程 注&#xff1a;《深入浅出Java多线程》是一本书&#xff0c;小编看的是它的 pdf&#xff0c;上面那个网页和书中内容是一致的。小编在起初学习多线程的时候是通过看视频的形式&#xff0c;学的模模糊糊的&#xff0c;这本书感觉很适合…

商务车改装后,有哪些情况会导致异响?

一、开车时出现了异响&#xff0c;主要由这些情况导致。&#xff08;1&#xff09;像商务车&#xff0c;二排基本都升级成了航空座椅&#xff0c;可能是出厂就有问题&#xff0c;拼接处没做好&#xff0c;导致座椅来回磨蹭。另外固定航空座椅螺丝没拧好&#xff0c;车子开动后会…

HTML5 <bdi> 标签、HTML5 <bdo> 标签

HTML5 <bdi> 标签 实例 将用户名从周围的文本方向设置中隔离出来&#xff1a; <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>w3cschool官网 - 编程狮&#xff0c;随时随地学编程</title> </head&g…