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)
})
相关推荐
天蓝色的鱼鱼9 分钟前
前端开发者的组件设计之痛:为什么我的组件总是难以维护?
前端·react.js
codingandsleeping10 分钟前
使用orval自动拉取swagger文档并生成ts接口
前端·javascript
石金龙1 小时前
[译] Composition in CSS
前端·css
白水清风1 小时前
微前端学习记录(qiankun、wujie、micro-app)
前端·javascript·前端工程化
Ticnix1 小时前
函数封装实现Echarts多表渲染/叠加渲染
前端·echarts
用户22152044278001 小时前
new、原型和原型链浅析
前端·javascript
阿星做前端1 小时前
coze源码解读: space develop 页面
前端·javascript
叫我小窝吧1 小时前
Promise 的使用
前端·javascript
NBtab2 小时前
Vite + Vue3项目版本更新检查与页面自动刷新方案
前端
天天扭码2 小时前
来全面地review一下Flex布局(面试可用)
前端·css·面试