做项目过程中多处需实现弹框效果,且弹框内容需自定义。
element-ui中虽有相关组件,但部分效果自定义较为繁琐,且样式不满足本项目需求。故考虑自定义一个弹框以达到统一样式、内容自定且方便复用的作用。

组件特点
  1. 可自定义弹框内容、大小、按钮类型、主题颜色、过渡效果等
  2. 可通过插槽自定义弹框主体内容
组件代码
<template>
  <transition name="slide">
    <div class="popup" :class="transition" v-show="showModule">
      <!-- 遮罩层 -->
      <div class="mask" v-if="mask"></div>
      <!-- 弹框 -->
      <div class="p-dialog" :style="{ '--theme-color': themeColor }">
        <!-- 1. 头部 -->
        <div class="p-header">
          <h4>{{ title }}</h4>
          <a href="javascript:;" class="iconfont icon-cuocha_kuai" @click="$emit('cancel')"></a>
        </div>
        <!-- 2. 内容(插槽) -->
        <div class="p-body">
          <slot name="body">content</slot>
        </div>
        <!-- 3. 底部(按钮) -->
        <div class="p-footer">
          <a href="javascript:;" class="btn" v-if="btn === 1" @click="$emit('submit')">{{ submitBtn }}</a>
          <a href="javascript:;" class="btn" v-if="btn === 2" @click="$emit('cancel')">{{ cancelBtn }}</a>
          <div class="btn-group" v-if="btn === 3">
            <a href="javascript:;" class="btn" @click="$emit('submit')">{{ submitBtn }}</a>
            <a href="javascript:;" class="btn btn-cancel" @click="$emit('cancel')">{{ cancelBtn }}</a>
          </div>
        </div>
      </div>
    </div>
  </transition>
</template>

<script>
export default {
  name: 'popup',
  props: {
    // 1. 弹框大小:包括 小 small 中 middle 大 large 表单 form
    size: {
      type: String,
      default: 'form',
    },
    // 2. 弹框标题
    title: {
      type: String,
      default: 'warning',
    },
    // 3. 按钮类型: 1 确定 2 取消 3 确定&取消
    btn: {
      type: Number,
      default: 3,
    },
    // 4. 按钮内容
    submitBtn: {
      type: String,
      default: 'submit',
    },
    cancelBtn: {
      type: String,
      default: 'cancel',
    },
    // 5. 是否显示遮罩层
    mask: {
      type: Boolean,
      default: true,
    },
    // 6. 选择弹框显示/隐藏的动画效果:top 从上方渐入渐出 fade 淡入淡出
    transition: {
      type: String,
      default: 'top',
    },
    // 7. 设置主题色
    themeColor: {
      type: String,
      default: '#cc6699',
    },
    showModule: Boolean,
  },
}
</script>

<style lang="scss" scoped>
// 弹框样式
.popup {
  z-index: 11;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  transition: all 0.5s;
  .mask {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: #000000;
    opacity: 0.5;
  }
  .p-dialog {
    position: absolute;
    top: 40%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 660px;
    background-color: #fff;
    border-radius: 3px;
    overflow: hidden;
    .p-header {
      height: 60px;
      background-color: var(--theme-color);
      line-height: 60px;
      padding: 0 25px;
      font-size: 16px;
      color: #fff;
      a {
        display: inline-block;
        position: absolute;
        right: 30px;
        top: 0px;
        color: #fff;
        font-size: 20px;
        transition: all 0.3s;
        &:hover {
          transform: scale(1.4);
        }
      }
    }
    .p-body {
      padding: 42px 40px 54px;
      font-size: #fff;
    }
    .p-footer {
      height: 72px;
      line-height: 72px;
      text-align: center;
      background-color: #f5f5f5;
    }
  }
}
// 按钮样式预设
.btn {
  display: inline-block;
  width: 110px;
  line-height: 30px;
  text-align: center;
  background-color: var(--theme-color);
  color: #fff;
  border: none;
  border-radius: 2px;
  cursor: pointer;
  transition: all 0.2s;
  &:hover {
    transform: scale(1.1);
  }
}

.btn-cancel {
  background-color: #999999;
}
// 弹框进出动画
// 从上方渐入渐出
.top {
  &.slide-enter-active {
    top: 0;
  }
  &.slide-leave-to {
    top: -100%;
  }
  &.slide-enter {
    top: -100%;
  }
}
// 淡入淡出
.fade {
  &.slide-enter-active {
    opacity: 1;
  }
  &.slide-leave-to {
    opacity: 0;
  }
  &.slide-enter {
    opacity: 0;
  }
}
</style>

参数说明
参数说明类型可选值默认值
size弹框预设大小选择stringsmall / middle / large / formform
title弹框顶部标题stringwarning
btn底部按钮类型number1 确定 / 2 取消 / 3 确定&取消3
submitBtn确定按钮文本stringsubmit
cancelBtn取消按钮文本stringcancel
mask是否显示遮罩层booleantrue / falsetrue
transition选择弹框显示/隐藏的动画效果stringtop 从上方渐入渐出 / fade 淡入淡出top
themeColor设置主题色(头部、底部按钮背景色)string#cc6699
showModule设置弹框显示隐藏的变量Boolean
事件绑定
事件说明
submit点击确认按钮触发的事件
cancel点击取消按钮 / 右上角 “x” 触发的事件
  • 其他说明
    使用插槽自定义内容时需要指定 v-slot:body
使用示例:
<popup 
title="新增信息" 
:btn="1" 
:showModule="showModule" 
submitBtn="确定"
cancelBtn="取消"
@cancel="showModule = false" 
@submit="submit" 
themeColor="#ff6600"
>
  <template v-slot:body>
    <div>
      ......
    </div>
  </template>
</popup>
import Popup from '@/components/module/popup.vue'
export default {
  name: 'xxx',
  components: {
    Popup,
  },
  data() {
    return {
      showModule: false,
    }
  },
  method: {
	submit() {
	  点击确认按钮触发的事件...
	}
  }
  
效果展示

(默认样式并绑定基本事件)
在这里插入图片描述

其他

该组件已修改并上传 npm 方便使用
地址:https://www.npmjs.com/package/m-popup-dialog

Logo

前往低代码交流专区

更多推荐