写了一个弹框组件
< 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- inputv- 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 | numbercode : 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>