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 相关文章推荐
ajax 文件上传应用简单实现
Mar 03 Javascript
google 搜索框添加关键字实现代码
Apr 24 Javascript
为Extjs加加速(javascript加速)
Aug 19 Javascript
理解JavaScript中的对象 推荐
Jan 09 Javascript
JS中window.open全屏命令解析及使用示例
Dec 11 Javascript
JavaScript的Number对象的toString()方法
Dec 18 Javascript
JS遍历页面所有对象属性及实现方法
Aug 01 Javascript
js绘制购物车抛物线动画
Nov 18 Javascript
利用angular.copy取消变量的双向绑定与解析
Nov 25 Javascript
vue.js系列中的vue-fontawesome使用
Feb 10 Javascript
axios如何利用promise无痛刷新token的实现方法
Aug 27 Javascript
vue项目前端微信JSAPI与外部H5支付相关实现过程及常见问题
Apr 14 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 Stream_*系列函数
2010/08/01 PHP
php preg_filter执行一个正则表达式搜索和替换
2012/02/27 PHP
完美实现wordpress禁止文章修订和自动保存的方法
2014/11/03 PHP
[原创]PHP实现逐行删除文件右侧空格的方法
2015/12/25 PHP
PHP实现在windows下配置sendmail并通过mail()函数发送邮件的方法
2017/06/20 PHP
打开超链需要“确认”对话框的方法
2007/03/08 Javascript
认识延迟时间为0的setTimeout
2008/05/16 Javascript
javascript new 需不需要继续使用
2009/07/02 Javascript
通用javascript脚本函数库 方便开发
2009/10/13 Javascript
javascript JSON操作入门实例
2010/04/16 Javascript
JS字符串函数扩展代码
2011/09/13 Javascript
JS与C#编码解码
2013/12/03 Javascript
javascript中字符串的定义示例代码
2013/12/19 Javascript
在浏览器中实现图片粘贴的jQuery插件-- pasteimg使用指南
2014/12/29 Javascript
pc加载更多功能和移动端下拉刷新加载数据
2016/11/07 Javascript
教你快速搭建Node.Js服务器的方法教程
2017/03/30 Javascript
JS表格组件神器bootstrap table使用指南详解
2017/04/12 Javascript
原生js实现随机点名
2020/07/05 Javascript
原生js实现弹幕效果
2020/11/29 Javascript
[03:03]2014DOTA2国际邀请赛 EG战队专访
2014/07/12 DOTA
Python实现PS图像调整之对比度调整功能示例
2018/01/26 Python
快速解决安装python没有scripts文件夹的问题
2018/04/03 Python
利用python如何处理nc数据详解
2018/05/23 Python
Python面向对象程序设计多继承和多态用法示例
2019/04/08 Python
python 提取文件指定列的方法示例
2019/08/07 Python
scikit-learn线性回归,多元回归,多项式回归的实现
2019/08/29 Python
linux环境下安装python虚拟环境及注意事项
2020/01/07 Python
浅析CSS3中鲜为人知的属性:-webkit-tap-highlight-color
2017/01/12 HTML / CSS
请解释在new与override的区别
2012/10/29 面试题
国家励志奖学金个人先进事迹材料
2014/05/04 职场文书
质量月口号
2014/06/20 职场文书
建筑学专业自荐书
2014/07/09 职场文书
运动会开幕式新闻稿
2015/07/17 职场文书
2015年环卫处个人工作总结
2015/07/27 职场文书
煤矿施工安全协议书
2016/03/22 职场文书
Python多线程实用方法以及共享变量资源竞争问题
2022/04/12 Python