vue3 - 自定义弹框组件

发布时间:2024年01月12日

在这里插入图片描述

写了一个弹框组件
<template>
  <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>
</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>
.myModal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.4);
  z-index: 100;

  .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;
      }
    }
  }
}
</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>

文章来源:https://blog.csdn.net/pig_ning/article/details/135544252
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。