vue 实现一个简单的全局调用弹窗案例


Posted in Javascript onSeptember 10, 2020

1.实现效果图

vue 实现一个简单的全局调用弹窗案例

2.第一步,新建一个.vue文件 定义一个弹框的基本模板

style样式放在了文章的最底部,如果需要看效果,需要将样式放入这个vue文件里,样式是用less写的,需要你的项目引入less

注意:我这里的组件右上角关闭是一张图片 需要换成你自己本地的路径

<template>
 <div id="tip_alertModal">
  <div class="t-alert-mask"></div>
  <div class="t-alert-container">
   <div class="t-alert-title">
    <span>
     {{title}}
    </span>
    <img @click="close" src="../../../static/images/alert/guanbi.png" alt="">
   </div>
   <div class="t-alert-content">
    <span class="content-text">
     {{content}}
    </span>
   </div>
   <div class="t-alert-confirm">
    <button @click="confirm">确定</button>
    <!-- 默认是没有取消按钮的,data定义默认true false -->
    <button class="cancel-btn" v-show="cancelBtn" @click="cancel">取消</button>
   </div>
  </div>
 </div>
</template>

<script>
 export default {
  data() {
   return {
    show: true, // 通过这个属性,控制是否移除dom元素
    title:'', // 顶部标题
    content:'', // 内容
    cancelBtn: false // 取消按钮
   };
  },
  methods: {
   close() {
    // 右上角关闭
    this.a_close && this.a_close();
    this.show = false;
    // 删除判断增加的window属性
    delete window.alertIsShow;
   },
   confirm() {
    // 确定
    this.a_confirm && this.a_confirm();
    this.show = false;
    // 删除判断增加的window属性
    delete window.alertIsShow;
   },
   cancel() {
    // 取消
    this.a_cancel && this.a_cancel();
    this.show = false;
    // 删除判断增加的window属性
    delete window.alertIsShow;
   }
  },
  watch: {
   show(cur, old) {
    // 通过监控data里的show属性 弹框有三个事件(右上角取消 确定按钮 取消按钮)
    // 每个事件写了 this.show = false
    // 当弹框出现的时候 点击任何一个事件 都会触发这里的监控事件 将页面上的弹框Dom移除
    if (cur === false) {
     let tip_alert = document.getElementById('tip_alertModal');
     tip_alert.parentNode.removeChild(tip_alert);
    }
   }
  }
 }
</script>

3.定义一个js文件

import Vue from 'vue'; 
import Alert from '@/components/public/alertModal'; //引入刚才写的弹框组件 
let AlertConstructor = Vue.extend(Alert); // 返回一个“扩展实例构造器” 

let AlertModal = (o) => {
 let alertDom = new AlertConstructor({
  el: document.createElement('div'); //将Alert组件挂载到新创建的div上 
 })
 document.body.appendChild(alertDom.$el); //把Alert组件的dom添加到body里 
 
 // 标题
 alertDom.title = o.title || '信息';
 // 单条内容
 alertDom.content = o.content;
 // 关闭按钮
 alertDom.cancelBtn = o.cancelBtn;

 // 弹框三个事件 右上角关闭 确定 取消
 alertDom.a_close = o.close || null;
 alertDom.a_confirm = o.confirm || null;
 alertDom.a_cancel = o.cancel || null;

}
export default AlertModal;

4.mian.js

import alert from '@/common/alertModal' //这里引入的是js文件

Vue.prototype.$alert = alert;

5.在任意组件调用

<template>
 <div>
  <button @click="operate">点击调用弹框</button>
 </div>
</template>

<script>
export default {
 methods: {
  operate() {
   this.$alert({
    title: '信息',
    content: '登入成功!',
    cancelBtn: true, //这个是启用取消按钮,
    close() {
     // 这里执行点击右上角需要做的事,默认执行关闭弹框
    },
    confirm() {
     // 这里执行点击确定按钮需要做的事,默认执行关闭弹框
    },
    cancel() {
     // 这里执行点击取消按钮需要做的事,默认执行关闭弹框
    }
   })
  }
 }
}
</script>

取消按钮开启

vue 实现一个简单的全局调用弹窗案例

调用之后是往body添加元素

vue 实现一个简单的全局调用弹窗案例

5.通过window.alertIsShow,给window增加一个属性,来控制一个页面只会出现一个弹框

methods: {
  operate () {
   if (!window.alertIsShow) {
    // 弹框模板有个 delete window.alertIsShow 是为了弹框关闭之后能再次显示
    this.$alert({
     title: '信息',
     content: '登入成功!',
     cancelBtn: true,
     close () {
      // 这里执行点击右上角需要做的事,默认执行关闭弹框
     },
     confirm () {
      // 这里执行点击确定按钮需要做的事,默认执行关闭弹框
     },
     cancel () {
      // 这里执行点击取消按钮需要做的事,默认执行关闭弹框
     }
    })
    window.alertIsShow = true;
   }
  }
 }

6.最后是弹框组件的less样式

<style lang="less" scoped>
 #tip_alertModal {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 100;
  width: 100%;
  height: 100%;
  
  .t-alert-mask {
   position: absolute;
   top: 0;
   left: 0;
   width: 100%;
   height: 100%;
   background-color: rgba(0, 0, 0, .3);
  }

  .t-alert-container {
   position: absolute;
   top: 50%;
   left: 50%;
   min-width: 240px;
   max-width: 400px;
   height: auto;
   background-color: #fff;
   transform: translate(-50%, -50%);
   border-radius: 4px;

   .t-alert-title {
    position: relative;
    width: 100%;
    height: 40px;
    line-height: 40px;
    background-color: rgba(115, 134, 255, 1);
    border-radius: 4px 4px 0px 0px;

    span {
     position: absolute;
     top: 50%;
     left: 10px;
     font-weight: 500;
     font-size: 16px;
     color: #fff;
     transform: translate(0, -50%);
    }

    img {
     position: absolute;
     top: 50%;
     right: 10px;
     transform: translate(0, -50%);
     cursor: pointer;
    }
   }

   .t-alert-content {
    text-align: center;
    span {
     font-family: PingFangSC-Regular;
     font-weight: 400;
     font-size: 14px;
     color: rgba(51,51,51,1);
    }

    span.content-text {
     display: inline-block;
     width: 100%;
     height: auto;
     font-weight: 400;
     font-size: 14px;
     color: #333;
     padding: 20px 18px;
    }
    .t-content-list {
      min-width: 320px;
      height: auto;
      text-align: left;
     .list-title {
      position: relative;
      padding: 10px 0 10px 10px;
      img {
       display: inline-block;
       position: absolute;
       width: 20px;
       margin-right: 10px;
      }
      span {
       display: inline-block;
       vertical-align: middle;
       padding-left: 31px;
      }
     }
     .list-content {
      width: 100%;
      height: auto;
      ul {
       padding-bottom: 10px;
       li {
        width: 100%;
        height: auto;
        padding-bottom: 10px;
        span {
         vertical-align: top;
        } 
        span.title {
         display: inline-block;
         padding-left: 41px;
         padding-right: 3px;
         text-align: left;
        }
       }
      }
     }
    }
   }

   .t-alert-confirm {
    width: 100%;
    padding-bottom: 17px;
    text-align: center;

    button {
     display: inline-block;
     width: 80px;
     height: 36px;
     border: none;
     background: rgba(115, 134, 255, 1);
     font-weight: 400;
     font-size: 16px;
     color: #fff;
     border-radius: 4px;
     outline: none;
     cursor: pointer;
    }
    .cancel-btn {
     margin-left:20px;
     background:rgba(151,193,234,1);
     font-family: PingFangSC-Regular;
     font-weight: 400;
     font-size: 16px;
     color: rgba(255,255,255,1);  
    }
   }
  }
 }
</style>

如果本篇文章对你有帮助的话,很高兴能够帮助上你。

补充知识:Vue注册全局组件-弹窗组件

在src目录下新建components文件夹

1.新建module文件夹,然后新建v-alert.vue

<template>
 <transition name="fade">
  <div
    class="v-alert g-center"
    :style="{zIndex}">
   <div
     class="v-cont"
     :class="{shadow:!hideCont}"
     :style="[innerWidth]">
    <div
      v-if="title.trim()"
      :style="[{backgroundColor:bgColorTit,color:cancelCol},titleStyle]"
      class="title g-font18">
     {{title}}
     <span class="title-data">{{titleData}}</span>
    </div>
    <div
      v-if="isCancel"
      class="v-cancel">
     <div
       class="cancel-icon"
       :style="{color:cancelCol}"
       @click="cancel">
      
     </div>
    </div>
    <slot name="slot3"></slot>
    <div
      v-if="!hideCont"
      :style="styles"
      class="content">
     <slot></slot>
    </div>
    <slot name="slot2"></slot>
   </div>
   <div
     class="g-fixed alert-wrap"
     @click="$emit('cancel')"
     :style="{backgroundColor:bgWrapColor}"></div>
  </div>
 </transition>
</template>
<script>
 export default {
  name: "v-alert",
  props: {
   title: {default: ""},
   // titFontSize:{default: '16'},
   bgColorTit: {default: "#40404C"},
   bgColor: {default: "#fff"}, // 背景色
   bgWrapColor: {default: "rgba(42, 47, 59, 0.6)"}, //外套背景色
   cancelCol: {default: "#fff"}, //按钮颜色
   width: {required: true, type: Number}, //宽度
   minWidth: {type: Number, default: 0},
   isCancel: {type: Boolean, default: true}, //是否显示关闭按钮
   titleData: {default: ""},
   hideCont: {type: Boolean, default: false}, //是否隐藏cont
   zIndex: {default: 2000},
   styles: {
    default() {
     return {};
    },
    type: Object
   },
   titleStyle: {
    default() {
     return {};
    },
    type: Object
   },
  },
  components: {},
  computed: {
   innerWidth() {
    let dfu = {
     backgroundColor: this.bgColor
    };
    this.minWidth > 0
     ? dfu.minWidth = `${this.minWidth}px`
     : dfu.width = `${this.width}px`;
    return dfu;
   }
  },
  methods: {
   cancel() {
    this.$emit("cancel");
   }
  },
  mounted() {
   document.addEventListener(
    "keydown",
    event => {
     let keyCode = this.$_lib.getKeycode(event);
     if (keyCode === 'Escape' || keyCode === 27) this.$emit("cancel");
    },
    false
   );
  }
 };
</script>
<style lang="scss"
  rel="stylesheet/scss"
  scoped>
 .v-alert {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 2000;
  .alert-wrap {
   top: 0;
   left: 0;
   width: 100%;
   height: 100%;
   /*z-index: 2000;*/
  }
  .v-cont {
   min-width: 100px;
   min-height: 100px;
   background-color: #ffffff;
   position: relative;
   border-radius: 2px;
   .shadow {
    box-shadow: 0 2px 30px rgba(42, 47, 59, 0.2);
   }
   z-index: 2001;
   .title {
    width: 100%;
    line-height: 70px;
    color: #ffffff;
    padding-left: 30px;
   }
   .title-data {
    color: #f8e19a;
   }
   .content {
    padding: 40px;
    /*padding: 60px 40px 50px 40px;*/
    word-wrap: break-word;
    text-align: left;
   }
  }
 
  .v-cancel {
   position: absolute;
   top: 0;
   right: 0;
   width: 100%;
   height: 70px;
  }
  .cancel-icon {
   position: absolute;
   text-align: center;
   width: 20px;
   height: 20px;
   line-height: 20px;
   right: 20px;
   top: 50%;
   margin-top: -10px;
   color: #ffffff;
   cursor: pointer;
   transition: 200ms;
   &:hover {
    -webkit-transform: rotate(90deg);
    -moz-transform: rotate(90deg);
    -ms-transform: rotate(90deg);
    -o-transform: rotate(90deg);
    transform: rotate(90deg);
   }
  }
 }
</style>

2.在nodule同级目录新建vue-component.js

import VAlert from './v-alert'; //弹窗
 
export default {
 install(Vue) {
  Vue.component('VAlert', VAlert);
 }
};

3.在main.js中注册为全局组件

import vueComponent from "./components/vue-component";

Vue.use(vueComponent);

4.在其他组件可以直接用了,无需import

<template>
  <v-alert
   v-if="is_alert"
   @cancel="is_alert=false"
   bg-color-tit="#40404C"
   cancel-col="#fff"
   :title="提示"
   :width="680">
   <div></div>
  </v-alert>
</template>

以上这篇vue 实现一个简单的全局调用弹窗案例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
(function($){...})(jQuery)的意思
Jul 22 Javascript
验证码按回车不变解决方法
Mar 29 Javascript
获取3个数组不重复的值的具体实现
Dec 30 Javascript
js无刷新操作table的行和列
Mar 27 Javascript
js 获取页面高度和宽度兼容 ie firefox chrome等
May 14 Javascript
jQuery 判断图片是否加载完成方法汇总
Aug 10 Javascript
使用jQuery操作HTML的table表格的实例解析
Mar 13 Javascript
完美解决IE不支持Data.parse()的问题
Nov 24 Javascript
了解JavaScript中let语句
May 30 Javascript
node.js中stream流中可读流和可写流的实现与使用方法实例分析
Feb 13 Javascript
JS指定音频audio在某个时间点进行播放
Nov 28 Javascript
React Fragment介绍与使用详解
Nov 11 Javascript
vue v-for 点击当前行,获取当前行数据及event当前事件对象的操作
Sep 10 #Javascript
vue 使用lodash实现对象数组深拷贝操作
Sep 10 #Javascript
Vue 按照创建时间和当前时间显示操作(刚刚,几小时前,几天前)
Sep 10 #Javascript
vue 导出文件,携带请求头token操作
Sep 10 #Javascript
vue radio单选框,获取当前项(每一项)的value值操作
Sep 10 #Javascript
jquery实现简单每周轮换的日历
Sep 10 #jQuery
vue循环中点击选中再点击取消(单选)的实现
Sep 10 #Javascript
You might like
PHP动态输出JavaScript代码实例
2015/02/12 PHP
使用php实现从身份证中提取生日
2016/05/09 PHP
thinkphp整合微信支付代码分享
2016/11/24 PHP
PHP实现Redis单据锁以及防止并发重复写入
2018/04/10 PHP
使用基于jquery的gamequery插件做JS乒乓球游戏
2011/07/31 Javascript
jQuery EasyUI API 中文文档 - Menu菜单
2011/10/03 Javascript
web性能优化之javascript性能调优
2012/12/28 Javascript
Ajax提交与传统表单提交的区别说明
2014/02/07 Javascript
javascript基本类型详解
2014/11/28 Javascript
jQuery实现contains方法不区分大小写的方法
2015/02/13 Javascript
JavaScript判断FileUpload控件上传文件类型
2015/09/28 Javascript
javascript弹出窗口实现代码
2015/11/12 Javascript
在Linux系统中搭建Node.js开发环境的简单步骤讲解
2016/01/26 Javascript
基于jQuery和hwSlider实现内容左右滑动切换效果附源码下载(一)
2016/06/22 Javascript
hovertree插件实现二级树形菜单(简单实用)
2016/12/28 Javascript
手写Node静态资源服务器的实现方法
2018/03/20 Javascript
React Native开发封装Toast与加载Loading组件示例
2018/09/08 Javascript
Nodejs 识别图片类型的方法
2019/08/15 NodeJs
vue 表单输入框不支持focus及blur事件的解决方案
2020/11/17 Vue.js
js属性对象的hasOwnProperty方法的使用
2021/02/05 Javascript
[52:41]OG vs IG 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/20 DOTA
python实现石头剪刀布程序
2021/01/20 Python
Python Flask框架模板操作实例分析
2019/05/03 Python
Python Sympy计算梯度、散度和旋度的实例
2019/12/06 Python
python GUI库图形界面开发之PyQt5 Qt Designer工具(Qt设计师)详细使用方法及Designer ui文件转py文件方法
2020/02/26 Python
matplotlib 三维图表绘制方法简介
2020/09/20 Python
Pytorch实现WGAN用于动漫头像生成
2021/03/04 Python
CSS3制作半透明边框(Facebox)类似渐变
2012/12/09 HTML / CSS
video下autoplay属性无效的解决方法(添加muted属性)
2020/05/19 HTML / CSS
linux系统都有哪些运行级别
2016/03/26 面试题
皮肤科医师岗位职责
2013/12/04 职场文书
员工拓展培训方案
2014/02/15 职场文书
淘宝客服工作职责
2014/07/11 职场文书
倡议书格式及范文
2015/04/29 职场文书
MySQL8.0.18配置多主一从
2021/06/21 MySQL
bat批处理之字符串操作的实现
2022/03/16 Python