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)
})
相关推荐
kyriewen1115 分钟前
异步编程:从“回调地狱”到“async/await”的救赎之路
开发语言·前端·javascript·chrome·typescript·ecmascript·html5
早點睡39017 分钟前
ReactNative项目Openharmony三方库集成实战:@react-native-clipboard/clipboard
javascript·react native·react.js
Old Uncle Tom17 分钟前
Markdown Viewer 再升级
前端
吴声子夜歌19 分钟前
JavaScript——数据类型
开发语言·javascript·ecmascript
Luna-player19 分钟前
Vue3中使用vue-awesome-swiper
前端·vue.js·arcgis
SuperEugene24 分钟前
Vue3 Pinia 状态管理规范:状态拆分、Actions 写法、持久化实战,避坑状态污染|状态管理与路由规范篇
前端·javascript·vue.js·前端框架·pinia
black方块cxy24 分钟前
实现一个输入框多个ip以逗号分隔最多20组,且ip不能重复
java·服务器·前端
@PHARAOH38 分钟前
WHAT - AI 时代下的候选人
大数据·前端·人工智能
竹林8181 小时前
从零到一:我在Solana NFT铸造前端中搞定@solana/web3.js连接与交易
前端·javascript
猪八宅百炼成仙1 小时前
不用点击也能预览图片:Element UI ImageViewer 命令式调用方案
前端