自己弹窗一个封装(vue,uniapp)

一、效果图:

二、项目中使用效果

1、弹窗一展示

this.popUpCallback是在你调用弹窗的页面写的方法,点击确定的回调

2、弹窗二展示

三、代码相关

1、popup.js

import Popup from './popup.vue'

export default {
  install(Vue) {
    const Profile = Vue.extend(Popup)

    // 弹出弹窗
    Vue.prototype.$openPopUp = function(params) {
      const instance = new Profile()
      for (const key in params) {
        if (Object.hasOwnProperty.call(params, key)) {
          const value = params[key]
          instance[key] = value
        }
      }
      instance.vm = instance.$mount()
      const popUpEle = document.body.lastElementChild
      if (popUpEle.className === 'popup-box') return
      setTimeout(() => document.body.appendChild(instance.vm.$el))
      return instance
    }

    // 关闭弹窗
    Vue.prototype.$closePopUp = function() {
      const instance = new Profile()
      instance.vm = instance.$mount()
      const popUpEle = document.body.lastElementChild
      if (popUpEle.className !== 'popup-box') return
      document.body.removeChild(popUpEle)
      return instance
    }
  }
}

2、main.js 直接挂载安装到全局

// 导入弹窗
import popup from './components/popup/popup.js'
// 安装插件
Vue.use(popup)

3、popup.vue

<template>
  <div class="popup-box">
    <view class="center-box" :style="[popUpWindowStyle]">
      <view class="header" :style="[headerStyle]">
        <view v-if="showTitle" class="title" :style="[titleStyle]">
          <text>{{ title }}</text>
        </view>
        <view v-if="imageUrl" class="img">
          <image
            :src="imageUrl"
            mode="scaleToFill"
            :style="[{width:`${imageWidth}rpx`},{height:`${imageHeight}rpx`}]"
          />
          <view v-if="redDotText != 'X'" class="redDot" :style="[{right: `calc( 50% - ${imageWidth}rpx )`}]">
            <text>
              {{ "+" + redDotText }}
            </text>
          </view>
        </view>
        <view class="textBox">
          <view v-if="bigText" class="bigText" :style="[bigTextStyle]">
            <text>
              {{ bigText }}
            </text>
          </view>
          <view v-if="smallText" class="smallText" :style="[smallTextStyle]">
            <text>
              {{ smallText }}
            </text>
          </view>
        </view>
      </view>
      <view class="footer">
        <view v-if="showCancel" class="btnBox">
          <view class="btn cancelBtn" @tap="closePopUp(0)">{{ cancelText }}</view>
        </view>
        <view class="btnBox">
          <view class="btn sureBtn" @tap="closePopUp(1)">{{ sureText }}</view>
        </view>
      </view>
    </view>
  </div>
</template>

<script>

export default {
  name: 'Popup',

  props: {
    success: {
      type: Function,
      default: undefined
    }, // 确定的回调
    cancel: {
      type: Function,
      default: undefined
    }, // 取消的回调
    headerStyle: {
      type: Object,
      default: () => {}
    }, // 头部样式
    showTitle: {
      type: Boolean,
      default: true
    }, // 是否展示标题(默认展示)
    title: {
      type: String,
      default: '提示'
    }, // 标题
    showCancel: {
      type: Boolean,
      default: false
    }, // 是否展示取消按钮(默认不展示)
    titleStyle: {
      type: Object,
      default: () => {}
    }, // 标题样式不会覆盖掉标题大小以及颜色
    popUpWindowStyle: {
      type: Object,
      default: () => {}
    }, // 弹窗窗口样式
    imageUrl: {
      type: String,
      default: ''
    }, // 图片地址(没有就不显示,图片地址相对位置以当前文件(就是这个文件)为基准)
    imageWidth: {
      type: Number,
      default: 116
    }, // 图片宽度
    imageHeight: {
      type: Number,
      default: 116
    }, // 图片宽度
    redDotText: {
      type: String,
      default: 'X'
    }, // 图片右上角小红点数字
    bigText: {
      type: String,
      default: '这是一个提示弹窗'
    }, // 大文本
    bigTextStyle: {
      type: Object,
      default: () => {}
    }, // 大文本样式
    smallText: {
      type: String,
      default: ''
    }, // 小文本
    smallTextStyle: {
      type: Object,
      default: () => {}
    }, // 小文本样式
    cancelText: {
      type: String,
      default: '取消'
    }, // 取消按钮文本
    sureText: {
      type: String,
      default: '确定'
    } // 确认按钮文本
  },

  data() {
    return {}
  },

  mounted() {
  },

  methods: {
    closePopUp(flag) {
      this.$closePopUp() // 关闭弹窗
      if (flag === 1 && this.success) {
        this.success()
      } else if (flag === 0 && this.cancel) {
        this.cancel()
      }
    }
  }
}
</script>
<style scoped>
.popup-box {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background: rgba(0,0,0,0.5);
  z-index: 9999;
}
.popup-box .center-box {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 532rpx;
  border-radius: 24rpx;
  opacity: 1;
  background: rgba(255,255,255,1);
}
.popup-box .center-box .header {
  padding: 30rpx;
  border-bottom:  rgba(235, 237, 240, 1) solid 2rpx;
  /* margin叠加问题 */
  /* overflow: hidden; */
}
.popup-box .center-box .header .title{
  font-size: 32rpx;
  font-weight: 500;
  text-align: center;
  margin-bottom: 40rpx;
  /* background-color: aqua; */
}
.popup-box .center-box .header .img{
  position: relative;
}
.popup-box .center-box .header .img .redDot{
  position: absolute;
  top: 0;
  right: calc( 50% - 116rpx);
  font-weight: 700;
  color: rgba(241, 58, 58, 1);
  text-align: left;
}
.popup-box .center-box .header .img image{
  width: 116rpx;
  height: 116rpx;
  display: block;
  margin: 30rpx auto;
}
.popup-box .center-box .header .textBox{
  margin: 20rpx 30rpx;
}
.popup-box .center-box .header .textBox .bigText {
  margin-top: 40rpx;
  font-size: 28rpx;
  line-height: 44rpx;
  font-weight: 400;
  color: rgba(35, 47, 63, 1);
  text-align: center;
}
.popup-box .center-box .header .textBox .smallText {
  margin-top: 16rpx;
  font-size: 24rpx;
  font-weight: 400;
  line-height: 40rpx;
  color: #929292;
}
.popup-box .center-box .footer {
  display: flex;
  width: 100%;
}
.popup-box .center-box .footer .btnBox {
  width: 50%;
  height: 90rpx;
  line-height: 90rpx;
  font-size: 32rpx;
  font-weight: 400;
  text-align: center;
  flex: 1;
}
.popup-box .center-box .btnBox .btn {
  color: rgba(161, 166, 179, 1);
}
.popup-box .center-box .btnBox .btn.sureBtn {
  color: rgba(241, 58, 58, 1);
}
</style>

4、prop

success: {
  type: Function,
  default: undefined
}, // 确定的回调
cancel: {
  type: Function,
  default: undefined
}, // 取消的回调
headerStyle: {
  type: Object,
  default: () => {}
}, // 头部样式
showTitle: {
  type: Boolean,
  default: true
}, // 是否展示标题(默认展示)
title: {
  type: String,
  default: '提示'
}, // 标题
showCancel: {
  type: Boolean,
  default: false
}, // 是否展示取消按钮(默认不展示)
titleStyle: {
  type: Object,
  default: () => {}
}, // 标题样式不会覆盖掉标题大小以及颜色
popUpWindowStyle: {
  type: Object,
  default: () => {}
}, // 弹窗窗口样式
imageUrl: {
  type: String,
  default: ''
}, // 图片地址(没有就不显示,图片地址相对位置以当前文件(就是这个文件)为基准)
imageWidth: {
  type: Number,
  default: 116
}, // 图片宽度
imageHeight: {
  type: Number,
  default: 116
}, // 图片宽度
redDotText: {
  type: String,
  default: 'X'
}, // 图片右上角小红点数字
bigText: {
  type: String,
  default: '这是一个提示弹窗'
}, // 大文本
bigTextStyle: {
  type: Object,
  default: () => {}
}, // 大文本样式
smallText: {
  type: String,
  default: ''
}, // 小文本
smallTextStyle: {
  type: Object,
  default: () => {}
}, // 小文本样式
cancelText: {
  type: String,
  default: '取消'
}, // 取消按钮文本
sureText: {
  type: String,
  default: '确定'
} // 确认按钮文本

四、解释

1、弹窗样式啥的可以自己在popup.vue文件中修改

2、使用this.$openPopUp调用,使用this.$closePopUp关闭

3、全局挂载在mian.j,全局皆可使,可自行修改挂载位置

4、本文知识点涉及到了vue的组件传值以及组件挂载使用等,可以去查阅相关知识点,不多啰嗦

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
好的,我可以为您提供一个简单的全局vue弹窗封装方法: 1. 首先,在您的Vue项目中创建一个名为"GlobalDialog"的组件,该组件应该包含一个弹窗的HTML结构和相应的样式。 2. 在您的Vue项目中创建一个名为"DialogPlugin"的插件,该插件应该包含一个全局方法,用于在任何组件中调用弹窗。 3. 在"DialogPlugin"插件中,使用Vue.prototype.$dialog = GlobalDialog来将"GlobalDialog"组件注册为全局方法。 4. 在任何组件中,您现在可以使用this.$dialog来调用弹窗,例如:this.$dialog.show()。 下面是示例代码: // GlobalDialog.vue <template> <div class="dialog"> <div class="dialog-overlay" v-show="visible"></div> <div class="dialog-content" v-show="visible"> <slot></slot> </div> </div> </template> <script> export default { data() { return { visible: false }; }, methods: { show() { this.visible = true; }, hide() { this.visible = false; } } }; </script> <style> .dialog { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 9999; } .dialog-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); } .dialog-content { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: #fff; padding: 20px; border-radius: 5px; } </style> // DialogPlugin.js import GlobalDialog from "./GlobalDialog.vue"; export default { install(Vue) { Vue.prototype.$dialog = GlobalDialog; } }; // main.js import Vue from "vue"; import DialogPlugin from "./DialogPlugin.js"; Vue.use(DialogPlugin); // Example.vue <template> <div> <button @click="showDialog">Show Dialog</button> <global-dialog> <h2>Hello World!</h2> <p>This is a global dialog.</p> <button @click="hideDialog">Close</button> </global-dialog> </div> </template> <script> export default { methods: { showDialog() { this.$dialog.show(); }, hideDialog() { this.$dialog.hide(); } } }; </script>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值