vue extend + promise封装全局弹窗组件

27 篇文章 0 订阅
25 篇文章 0 订阅
因为项目没有引入第三方UI库,所以所有的公共组件都需要自己封装
  • 现在需要一个全局的弹窗,要有promise异步处理
  • 实现后的效果

在这里插入图片描述

// components/confirm文件
<template>
  <div class="popup-wrap" v-if="showPopup">
    <div class="popup-center">
      <div class="popup-content">
        <div class="popup-close" @click="close"></div>
        <div class="title">{{ title }}</div>
        <div class="describe">{{ content }}</div>
        <div class="btn">
          <div :class="['btn-right', active == 'cancal' ? 'active' : '']" @click="handleClick('cancal')">{{cancelBtnText}}</div>
          <div :class="['btn-right', active == 'yes' ? 'active' : '']" @click="handleClick('yes')">{{yesBtnText}}</div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      showPopup: false,
      title: "", //标题
      content: "", //提示文字
      yesBtnText: "", //确定按钮
      cancelBtnText: "", //取消按钮
      promiseStatus: null,
      active: "",
    };
  },
  watch: {},
  props: {},
  mounted () {
    this.confirm()
  },
  methods: {
    confirm() {
      this.showPopup = true;
      return new Promise((resolve, reject) => {
        this.promiseStatus = { resolve, reject };
      });
    },
    handleClick(e) {
      this.active = e;
      if (e == "yes") {
        this.promiseStatus && this.promiseStatus.resolve();
      } else {
        this.promiseStatus && this.promiseStatus.reject();
      }
      this.showPopup = false
    },
    close() {
      this.showPopup = false
       this.promiseStatus && this.promiseStatus.reject();
      // this.$emit("close");
    },
  },
};
</script>
<style lang="less" scoped>
.popup-wrap {
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.6);
  position: fixed;
  top: 0rem;
  left: 0rem;
  right: 0rem;
  bottom: 0rem;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  .popup-center {
    width: 990px;
    height: 413px;
    background-size: 990px 413px;
    display: flex;
    align-items: center;
    justify-content: center;
    .popup-content {
      position: absolute;
      width: 970px;
      height: 393px;
      background: linear-gradient(
        180deg,
        rgba(5, 20, 39, 0.9) 0%,
        rgba(3, 17, 33, 0.9) 54%,
        rgba(1, 33, 74, 0.9) 100%
      );
      .popup-close {
        cursor: pointer;
        position: relative;
        top: 45px;
        left: 900px;
        width: 26px;
        height: 26px;
        border: 1px solid #fff;
        background-size: 100% 100%;
      }
      .title {
        text-align: center;
        margin-top: 50px;
        font-size: 40px;
        font-family: PingFangSC-Semibold, PingFang SC;
        font-weight: 600;
        color: #258df9;
        line-height: 56px;
        background: linear-gradient(180deg, #afebff 0%, #ffffff 100%);
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
      }
      .describe {
        text-align: center;
        margin-top: 30px;
        font-size: 28px;
        font-family: PingFangSC-Regular, PingFang SC;
        font-weight: 400;
        color: #a4bace;
        line-height: 40px;
      }
    }
  }
  .btn {
    width: 540px;
    height: 76px;
    margin: 0 auto;
    margin-top: 45px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    .btn-right {
      cursor: pointer;
      width: 200px;
      height: 76px;
      border: 2px solid #a4bace;
      font-size: 30px;
      font-family: PingFangSC-Regular, PingFang SC;
      font-weight: 400;
      color: #a4bace;
      line-height: 76px;
      text-align: center;
      &.active {
        border: 2px solid #258df9;
        background: rgba(37, 141, 249, 0.3);
        color: #afebff;
      }
    }
  }
}
</style>
// js文件,这个文件看你们自己吧,写在哪里都可以
// utils/confirm.js
import Confirm from '@/components/confirm.vue'
import Vue from "vue";
const ConfirmBox = Vue.extend(Confirm);
/* @使用方法 this.$confirm进行调用
 * this.$confirm("此操作将永久删除该文件, 是否继续?", "确定执行删除操作吗", {
      cancelBtnText: "取消",
      yesBtnText: "确认执行",
    })
    .then(() => {
      console.log("点击了确认按钮");
    })
    .catch(() => {
      console.log("点击了取消按钮cancel");
    });
 */
  Confirm.install = (content, title, options) => {
    if (typeof title === 'object') {
      options = title;
      title = '';
    } else if (title === undefined) {
      title = '';
    }
  
    options = Object.assign({
      title: title,
      content: content,
    }, options);
  
    let instance = new ConfirmBox({
      data: options
    }).$mount();
    document.body.appendChild(instance.$el);
    return instance.confirm();
  };
// mine.js 在根路径进行挂载
import "@/util/confirm" // 引入js
import Confirm from '@/components/confirm'  //Confirm组件
Vue.config.productionTip = false //阻止启动生产消息,常用作指令  消息提示的环境配置,设置为开发环境或者生产环境
Vue.prototype.$confirm = Confirm.install; //Confirm组
// 使用 
// home.vue
<template>
	<div @click="handleClick">点击</div>
</template>

<script>
export.default = {
	data () {},
	methdos: {
		handleClick () {
			this.$confirm("此操作将永久删除该文件, 是否继续?", "确定执行删除操作吗", {
		        cancelBtnText: "取消",
		        yesBtnText: "确认执行",
		      })
		      .then(() => {
		        console.log("点击了确认按钮");
		      })
		      .catch(() => {
		        console.log("点击了取消按钮cancel");
		      });
		}
	}
}
</script>
Vue3封装全局弹窗组件的步骤如下: 1. 创建一个Vue实例,作为全局弹窗组件的容器。可以使用`createApp`方法创建Vue实例,并将其挂载到一个DOM元素上。 2. 在全局弹窗组件上定义必要的属性和方法。比如,可以定义一个`visible`属性控制弹窗的显示与隐藏,一个`title`属性用于显示弹窗的标题,一个`content`属性用于显示弹窗的内容等。 3. 在全局弹窗组件内部实现弹窗的样式和交互逻辑。可以使用Vue的模板语法和样式定义实现弹窗的外观和样式效果,并通过Vue的响应式特性,实现弹窗的交互逻辑,比如点击关闭按钮时隐藏弹窗。 4. 添加全局方法,在Vue实例的原型上添加一个方法,用于在任意组件中调用弹窗组件。可以使用`app.config.globalProperties`来添加全局方法,以便在任何地方都可以访问到该方法。 5. 在组件中使用全局弹窗组件。在需要显示弹窗组件中,通过调用全局方法来调用弹窗组件。可以通过传递参数的方式,动态设置弹窗的内容和样式。 6. 在全局弹窗组件的内部实现弹窗的生命周期钩子函数,比如`mounted`函数用于在弹窗组件被挂载到DOM后执行相应的逻辑。 通过以上步骤,就可以封装一个可在任何组件中使用的全局弹窗组件。在使用过程中,只需要调用全局方法,传入相应的参数,即可显示自定义的弹窗内容和样式,提供更好的用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值