Vue弹窗 Confirm 组件

Vue的弹窗组价

描述:有时候本身开发项目,须要使用到一些弹窗,提示框之类的东西。通常会有咱们本身使用一些UI组件库,或者本身手写一个。
哈哈,用别人的东西有时候挺好的,可是有时候又很差,由于业务的需求和UI的设计老是变化的很快,别人的东西不免改起来不少时候感受还不如本身写(反正不少时候我都是这样的感受,特别是踩到坑时,每每以为莫名其妙,不知如何是好,可是本身写的东西不同,能够调试)。因此这里仍是决定本身造一个轮子。
本文章东西不会讲的太深,可是感受写完,遇到的问题仍是挺有意思的。
模仿了VUX的风格,上一个效果图:javascript

这里写图片描述

这里写图片描述

注:本文章所描述的东西只限于 Vue 的项目参考。css

使用

代码会在后面给出,其实就是一个 .vue 文件的内容,你只要在项目新建一个文件,就像引入本身的组件同样就能够。惟一须要注意的就是父元素的调用方式和VUX的不太同样(若是你曾使用过的话),我的以为VUX的方式在使用的时候声明的变量有点多,特别是引入了Alert,Toast,Spinner等组价之后,就须要声明不少额外的变量控制,比较乱,因此换了一种调用方式,使用时,只要:html

  1. import 引进 Confirm 组件,假设组件名是:Confirm;
  2. 给组价一个 ref 的引用,好比:<confirm ref="myConfirm"></confirm>
  3. 而后父组件只要经过:this.$refs.myConfirm.show(content, configObj) 或者 this.$refs.myConfirm.hidden() 开启和关闭弹窗就好,至于控制里面的内容,就在 show 方法经过配置就好。后面会给出详细的配置信息。

这样设计交互的好处就是减小了中间和控制变量的声明,使用更方面一些。vue

代码

<template> <transition name="confirm-fade"> <div v-if="isShowConfirm" class="my-confirm" @click.stop="clickFun('clickCancel')"> <div class="confirm-content-wrap" @click.stop> <h3 class="my-confirm-title">{{ titleText }}</h3> <p class="my-confirm-content">{{ content }}</p> <div class="my-operation"> <div v-if="type==='confirm'" class="my-cancel-btn" @click="clickFun('clickCancel')"> <p class="my-btn-text my-border-right">{{ cancelText }}</p> </div> <div class="confirm-btn" @click="clickFun('clickConfirm')"> <p class="my-btn-text">{{ confirmText }}</p> </div> </div> </div> </div> </transition> </template> <script type="text/ecmascript-6"> export default { data () { return { isShowConfirm: false, // 用于控制整个窗口的显示/隐藏 titleText: '操做提示', // 提示框标题 content: 'Say Something ...', // 提示框的内容 cancelText: '取消', // 取消按钮的文字 confirmText: '确认', // 确认按钮的文字 type: 'confirm', // 代表弹框的类型:confirm - 确认弹窗(有取消按钮);alert - 通知弹框(没有取消按钮) outerData: null // 用于记录外部传进来的数据,也能够给外部监听userBehavior,事件的函数提供判断究竟是哪一个事件触发的 } }, methods: { show (content, config) { this.content = content || 'Say Something ...' if (Object.prototype.toString.call(config) === '[object Object]') { // 确保用户传递的是一个对象 this.titleText = config.titleText || '操做提示' this.cancelText = config.cancelText || '取消' this.confirmText = config.confirmText || '确认' this.type = config.type || 'confirm' this.outerData = config.data || null } this.isShowConfirm = true }, hidden () { this.isShowConfirm = false this.titleText = '操做提示' this.cancelText = '取消' this.confirmText = '确认' this.type = 'confirm' this.outerData = null }, clickFun (type) { this.$emit('userBehavior', type, this.outerData) this.hidden() } } } </script> <style scoped> .my-confirm { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.5); z-index: 998; /* 这里防止当用户长按屏幕,出现的黑色背景色块,以及 iPhone 横平时字体的缩放问题 */ -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } /* 进入和出去的动画 */ .confirm-fade-enter-active { animation: opacity 0.3s; } .confirm-fade-enter-active .confirm-content-wrap { animation: scale 0.3s; } .confirm-fade-leave-active { animation: outOpacity 0.2s; } /* 包裹层容器样式 */ .confirm-content-wrap { position: absolute; top: 28%; left: 0; right: 0; width: 280px; margin: 0 auto; background-color: #fff; border-radius: 5px; z-index: 999; user-select: none; } /* 顶部标题部分 */ .my-confirm-title { padding-top: 20px; text-align: center; font-size: 20px; font-weight: 500; color: #333; } /* 中间内容部分 */ .my-confirm-content { padding: 0 15px; padding-top: 20px; margin-bottom: 32px; text-align: center; font-size: 16px; color: #666; line-height: 1.5; } /* 底部按钮样式 */ .my-operation { display: flex; border-top: 1px solid #eee; } .my-operation .my-cancel-btn, .confirm-btn { flex: 1; } .my-operation .confirm-btn { color: #ffb000; } .my-operation .my-btn-text { text-align: center; font-size: 16px; margin: 14px 0; padding: 6px 0; } /* 其余修饰样式 */ .my-border-right { border-right: 1px solid #eee; } /* 进来的动画 */ @keyframes opacity { 0% { opacity: 0; } 100% { opacity: 1; } } @keyframes scale { 0% { transform: scale(0); } 60% { transform: scale(1.1); } 100% { transform: scale(1); } } /* 出去的动画 */ @keyframes outOpacity { 0% { opacity: 1; } 100% { opacity: 0; } } </style> 

属性

这里的属性放置于 this.$refs.myConfirm.show(content, configObj) 中的参数。java

  • titleText (String) 弹框的提示标题
  • content (String) 弹框的主体内容
  • confirmText (String) 弹框的确认按钮文字
  • cancelText (String) 取消按钮文字
  • type (confirm | alert) 弹窗的类型:带取消按钮的确认框和不带取消按钮的确认框
  • outerData (*) 外部传进来的数据,会在用户点击确认按钮时,原封不动的发送出去,便于作一些数据交互,也能够用于区分多个弹窗

事件

这里只提供一个事件供用户点击确认/取消按钮,只有一个事件,怎么区分呢?
答案就在事件提供的参数里面:web

<confirm ref="myConfirm" @userBehavior="userBehaviorFun"></confirm>

userBehavior 事件会默认提供两个参数 : typedataexpress

其中type只多是一下两个值之一ecmascript

  1. clickCancel 用户点击了确认按钮
  2. clickCancel 用户点击了取消按钮,也有多是点击了背景遮罩,都认为是为无效的取消按钮

data 的值,就是用户出传进来的东西,用途普遍,能够是下一步函数的参数,也能够是区分多个弹框的逻辑svg

不带取消按钮的弹框

由于默认的弹框是带取消按钮的,因此只要给 show() 方法中传入第一个内容参数基本就好,比较简单,就不说了。
可是有时候须要仿照 Alert 框给用户一个,仅仅只是通知的弹框,此时只须要配置一会就好:函数

this.$refs.confirmRefs.show('注册成功!', {
    type: 'alert',
    confirmText: '肯定',
    titleText: '消息提示',
    data: '我是外界传进来的数据'
})

效果就是开始的第二站图片。至此,弹框的部分就算是基本结束了!

画外音

这里组件几乎快要完成的时候,经过手机真机测试的时候发现一写小问题,这里没有办法截图。就是当用户点击按钮的时候(弹框的其余内容也会)会出现一个半透明的黑色背景,虽然不影响使用,可是看着就是很不爽,百度了一下,仍是解决了,移动端一直就会出现的问题,不过解决起来也很容易,只要加上:

html,body{ -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); }

就好哦,详情看这里:移动端HTML5点击事件闪现灰色背景解决方案

因此,这里作下来,本身写了一遍,感受仍是收获了不少东西,虽然只是一个很简单的弹框,须要真的写好仍是不容易的,但愿你们看到了,能够多动手写一些。不至于平时在工做中遇到问题无从下手。

困了死了,今天是周五团队TB了,吃了大庙火锅,味道不错,喝了点啤酒,催着空调,如今加班写这个感受整我的都是飘飘然,中间确定有不少东西被我忽略了。
哎,溜了…

版本记录: 2018/09/15 00:12 发布博客