写了一个弹框组件
< 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;
. 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;
}
}
}
}
. modal- fade- enter- active, . modal- fade- leave- active {
transition : opacity 0 . 5s;
}
. modal- fade- enter, . modal- fade- leave- to {
opacity : 0 ;
}
< / 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>