vue实现原理this.$message

components 通用组件文件夹下 创建 esConfirm文件夹

创建 index.js js文件

javascript 复制代码
import Vue from 'vue';
import Confirm from './index.vue'; // 引入组件

let newInstance;
const ConfirmInstance = Vue.extend(Confirm); // 创建构造函数

const initInstance = () => { // 执行方法后完成挂载
	newInstance = new ConfirmInstance(); // 实例化
	document.body.appendChild(newInstance.$mount().$el);
// 实例化后手动挂载,得到$el真实Dom,将其添加到body最后
}

export default options => {
//导出一个方法,接受配置参数
if (!newInstance) {
	initInstance(); // 挂载
}
Object.assign(newInstance, options);
// 实例化后newInstance就是一个对象了,所以data内的数据会
// 挂载到this下,传入一个对象与之合并

return newInstance.show(vm => { // 显示弹窗
	newInstance = null; // 将实例对象清空
})
}

esConfirm文件夹下创建组件 index.vue

javascript 复制代码
<template>
  <!-- 二次确认弹窗 -->
  <el-dialog width="440px" class="delete-confirm" :visible.sync="confirmDialigShow" :show-close="false"
    :close-on-click-modal="false">
    <div class="top">
      <img class="danger" :src="require('./danger.png')">
      <div class="title">{{ title }}</div>
    </div>
    <div class="bottom">{{ content }}</div>
    <span slot="footer" class="dialog-footer">
      <el-button v-if="showCancelButton" size="small" @click="cancel">{{ cancelButtonText || '取消' }}</el-button>
      <el-button size="small" type="primary" @click="confirm">{{ confirmButtonText || '确定' }}</el-button>
    </span>
  </el-dialog>
</template>

<script>
export default {
  data() {
    return {
      title: '提示',
      content: '该数据删除将无法恢复,是否确认删除?',
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      showCancelButton: true,
      confirmDialigShow: true
    }
  },
  methods: {
    show(cb) {
      this.showFlag = true
      typeof cb === "function" && cb.call(this, this)
      return new Promise((resolve, reject) => {
        this.reject = reject
        this.resolve = resolve
      })
    },
    cancel() {
      this.reject("cancel")
      this.hide()
    },
    confirm() {
      this.resolve("confirm")
      this.hide()
    },
    hide() {
      this.showFlag = false
      document.body.removeChild(this.$el)
      this.$destroy()
    }
  }
}
</script>
<style lang='scss' scoped>
.delete-confirm {
  // width: 440px;
  box-shadow: 0px 4px 12px 0px rgba(0, 0, 0, 0.1);
  border-radius: 4px;

  .top {
    display: flex;
    align-items: center;
    margin-bottom: 12px;

    .danger {
      width: 30px;
      height: 24px;
      margin-right: 12px;
    }

    .title {
      font-weight: 500;
      font-size: 16px;
      color: rgba(0, 0, 0, 0.85);
      line-height: 24px;
    }
  }

  .bottom {
    font-size: 14px;
    font-weight: 400;
    color: #324457;
    line-height: 22px;
    margin-top: 20px;
  }

  ::v-deep .el-dialog__header {
    display: none;
  }

  ::v-deep {
    .el-dialog {
      margin-top: 20vh !important;
    }

    .el-dialog__body {
      padding: 24px;
    }

    .el-dialog__footer {
      border: none;
      line-height: 0;
      padding: 8px 24px 24px 0 !important;
    }
  }
}
</style>

在main.js 注册组件

javascript 复制代码
import esConfirm from '@/components/esConfirm/index.js'
Vue.prototype.$esConfirm = esConfirm

调用

javascript 复制代码
this.$esConfirm({
title: '是否删除?'
}).then(res => {
console.log(res)
}).catch(error => {
console.log(error)
})
相关推荐
Flynt4 小时前
axios 被投毒半年后,我把 npm 的"安全防线"实测了一遍:最信任的 SHA512 是安慰剂
前端·npm·node.js
excel5 小时前
Base62 和 Base64 有什么区别?
前端
风骏时光牛马6 小时前
大模型底层架构与AI源码深度剖析
前端
掘金挖土7 小时前
前端手摸手跑路之 AI 应用开发(九)
前端·后端
中文呀9 小时前
三维 GIS 离线缓存实战:逆向 CesiumOfflineCache,并亲手为它补上"自动更新"能力
前端
前进前进前进10 小时前
TRAE 全链路实战:做了一个警示牌一键生成器:纯 Canvas、单文件、零依赖
前端
小万74211 小时前
God‘s Eye View 深度解析:15 路公开信号 + CesiumJS 的浏览器级 OSINT 控制台,60 帧渲染的“真实间谍卫星模拟器”
前端
IT星宿11 小时前
浏览器标签页全是一个图标:我用名字哈希生成 favicon,让每个项目都有身份标识
前端
OpsEye11 小时前
大模型账单对账难:不同厂商 Token 统计口径差异怎么处理
javascript·ai编程