超级好用的弹框组件

1、index.vue

<template>
  <!-- :z-index="zIndex" -->
  <el-dialog :custom-class="className" :class="{
    'has-icon': hasIcon,
    'has-border': hasBorder
  }" :visible="visible" :width="width+'px'" :title="title" @close="$emit('close')">
    <div class="content-box">
      <slot>
        <template v-if="hasIcon">
          <i class="el-icon-warning"></i>
          <div class="title">{{title}}</div>
        </template>
        <div class="content">{{content}}</div>
      </slot>
    </div>
    <el-row type="flex" justify="center" slot="footer">
      <el-button type="primary" @click="$emit('success')">确认</el-button>
      <el-button type="default" @click="$emit('close')">取消</el-button>
    </el-row>
  </el-dialog>
</template>

<script>
export default {
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    title: {
      type: String,
      default: '提示'
    },
    // 是否有警告图标
    hasIcon: {
      type: Boolean,
      default: true
    },
    // 是否有头部底部线
    hasBorder: {
      type: Boolean,
      default: false
    },
    width: {
      type: Number,
      default: 500
    },
    // zIndex: {
    //   type: Number,
    //   default: 3000
    // }
  },
  components: {},
  data() {
    return {
      className: 'confirm-dialog',
      content: ''
    };
  },
  created() {},
  mounted() {
    console.log('this', this);
  },
  methods: {},
  watch: {
  },
  computed: {}
};
</script>
<style lang="scss">
.el-dialog__wrapper {
  &.has-icon {
    .el-dialog__title {
      display: none;
    }
    .el-dialog__headerbtn {
      top: 10px;
    }
    .el-dialog__body {
      padding-top: 0px;
    }
    .content-box {
      align-items: center;
      flex-direction: column;
      i {
        font-size: 28px;
        color: #f67922;
      }
      .title {
        color: #0e0e0f;
        font-size: 18px;
        font-weight: 700;
        margin-top: 5px;
      }
      .content {
        color: #5e5f61;
        font-size: 14px;
        margin-top: 10px;
      }
    }
  }
  &.has-border {
    .el-dialog__header {
      border-bottom: 1px solid #EBECED;
    }
    .el-dialog__footer {
      border-top: 1px solid #EBECED;
    }
  }
}
.confirm-dialog {
  .el-dialog__header {
    padding: 14px 32px;
  }
  .el-dialog__title {
    color: #0e0e0f;
    font-size: 18px;
    font-weight: 700;
  }
  .column-center {
    align-items: center;
    display: flex;
    justify-content: center;
    flex-direction: column;
  }
  .red-tip {
    color: #ff0000;
  }

  .el-button {
    width: 60px;
    height: 32px;
    // line-height: 60px;
    padding: 0px;
  }
  .el-button--primary{
    background: #3065FF;
  }
  .el-button--default{
    color: #0E0E0F;
    border: 1px solid #D9DADB;
    &:hover{
      color: #0E0E0F;
      border: 1px solid #D9DADB;
      background-color: #fff;
    }
  }
}
</style>
<style lang="scss" scoped>
.content-box {
  display: flex;
  justify-content: center;
}
.color-red {
  color: #d8696b;
}
</style>

2、组件index.js

 

import confirmDialog from "./index.vue";
import dialog from "./dialog";
function install(Vue) {
  Vue.prototype.$confirmDialog = function (options) {
    return dialog(confirmDialog, {
      visible: true,
      ...options,
    });
  };
  Vue.prototype.$dialog = dialog;
}
export default {
  install,
};

3、 dialog.js

import Vue from "vue";
import { isVNode } from "element-ui/src/utils/vdom";
let instance = null;
export default function (Component, options) {
  let DialogConstructor = Vue.extend(Component);
  // console.log(propsData)
  if (!instance) {
    instance = new DialogConstructor({
      el: document.createElement("div"),
    });
    for (let prop in options) {
      if (options.hasOwnProperty(prop)) {
        instance[prop] = options[prop];
      }
    }
    if (isVNode(instance.content)) {
      instance.$slots.default = [instance.content];
      instance.content = null;
    } else {
      delete instance.$slots.default;
    }
    document.body.appendChild(instance.$el);
    Vue.nextTick(() => {
      instance.visible = true;
    });
    function close() {
      if (!instance) return;
      instance.$nextTick(() => {
        if (!instance) return;
        instance.$destroy(true);
        if (instance.$el.parentNode) {
          instance.$el.parentNode.removeChild(instance.$el);
        }
        instance = null;
      });
    }
    return new Promise((resolve, reject) => {
      let onClose = () => {
        instance.visible = false;
        reject();
        close();
      };
      let onSuccess = (data) => {
        resolve(data);
        close();
      };
      instance.$on("close", onClose);
      instance.$on("cancel", onClose);
      instance.$on("success", onSuccess);
      instance.$on("enter", onSuccess);
    });
  } else {
    return Promise.reject(new Error("请先关闭对话框"));
  }
}

4、在main.js中注册

import ConfirmDialog from "@/components/ConfirmDialog";
Vue.use(ConfirmDialog);

5、使用示例

  await this.$confirmDialog({
          visible: true,
          title: '提示',
          content: '修改暂计量比例,当前数据会重置,确认是否继续?'
        });

6、实际效果

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值