x-modal.vue 2.12 KB
Newer Older
qd01's avatar
qd01 committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
<template>
  <div v-if="visible" class="x-modal-wrap" @click.self="handleClose">
    <div class="x-modal" :class="{ 'hidden-title': !title }">
      <h3 v-if="title" class="x-modal-header">
        {{ title }}
      </h3>
      <div class="x-modal-body">
        <span>{{ content }}</span>
      </div>
      <div class="x-modal-footer">
        <button class="x-modal-btn" @click="handleOk">
          {{ okText }}
        </button>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup name="x-modal">
import { computed } from 'vue'

const props = withDefaults(defineProps<ModalProps>(), {
  okText: '好的',
})

const emit = defineEmits<{
  (e: 'update:visible', value: boolean): void
  (e: 'ok'): void
  (e: 'close'): void
}>()

interface ModalProps {
  visible: boolean
  content: string
  title?: string
  okText?: string
}

const visible = computed<boolean>({
  get() {
    return props.visible
  },
  set(val) {
    emit('update:visible', val)
  },
})

function handleOk() {
  visible.value = false
  emit('ok')
}

function handleClose() {
  visible.value = false
  emit('close')
}
</script>

<style lang="scss" scoped>
.x-modal {
  position: relative;
  width: 320px;
  margin-top: -10vh;
  padding: 26px 0;
  text-align: center;
  background-color: #fff;
  border-radius: 12px;

  &-wrap {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    background-color: rgb(0 0 0 / 75%);
  }

  &-header {
    margin: 0;
    padding: 5px 20px;
    color: #333;
    font-weight: bold;
    font-size: 18px;
  }

  &-body {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px 30px 26px;
    color: #888;
    font-size: 16px;
    line-height: 24px;
  }

  &-footer {
    padding: 0 30px;
  }

  &-btn {
    width: 250px;
    height: 50px;
    color: #fff;
    font-weight: bold;
    font-size: 18px;
    line-height: 50px;
    background: var(--color-primary);
    border: none;
    border-radius: 25px;
  }

  &.hidden-title {
    .x-modal-body {
      min-height: 88px;
    }
  }
}
</style>