Vue弹窗 Confirm 组件
Vue的弹窗组价
描述:有时候自己开发项目,需要使用到一些弹窗,提示框之类的东西。一般会有我们自己使用一些UI组件库,或者自己手写一个。
哈哈,用别人的东西有时候挺好的,但是有时候又不好,因为业务的需求和UI的设计总是变化的很快,别人的东西难免改起来很多时候感觉还不如自己写(反正很多时候我都是这样的感觉,特别是踩到坑时,往往觉得莫名其妙,不知如何是好,但是自己写的东西不一样,可以调试)。所以这里还是决定自己造一个*。
本文章东西不会讲的太深,但是感觉写完,遇到的问题还是挺有意思的。
模仿了VUX的风格,上一个效果图:
注:本文章所描述的东西只限于 Vue 的项目参考。
使用
代码会在后面给出,其实就是一个 .vue 文件的内容,你只要在项目新建一个文件,就像引入自己的组件一样就可以。唯一需要注意的就是父元素的调用方式和VUX的不太一样(如果你曾使用过的话),个人觉得VUX的方式在使用的时候声明的变量有点多,特别是引入了Alert,Toast,Spinner等组价以后,就需要声明很多额外的变量控制,比较乱,所以换了一种调用方式,使用时,只要:
- import 引进 Confirm 组件,假设组件名是:Confirm;
- 给组价一个 ref 的引用,比如:
<confirm ref="myConfirm"></confirm>
- 然后父组件只要通过:
this.$refs.myConfirm.show(content, configObj)
或者this.$refs.myConfirm.hidden()
开启和关闭弹窗就好,至于控制里面的内容,就在 show 方法通过配置就好。后面会给出详细的配置信息。
这样设计交互的好处就是减少了中间和控制变量的声明,使用更方面一些。
代码
<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)
中的参数。
-
titleText (String)
弹框的提示标题 -
content (String)
弹框的主体内容 -
confirmText (String)
弹框的确认按钮文字 -
cancelText (String)
取消按钮文字 -
type (confirm | alert)
弹窗的类型:带取消按钮的确认框和不带取消按钮的确认框 -
outerData (*)
外部传进来的数据,会在用户点击确认按钮时,原封不动的发送出去,便于做一些数据交互,也可以用于区分多个弹窗
事件
这里只提供一个事件供用户点击确认/取消按钮,只有一个事件,怎么区分呢?
答案就在事件提供的参数里面:
<confirm ref="myConfirm" @userBehavior="userBehaviorFun"></confirm>
userBehavior
事件会默认提供两个参数 : type
和 data
其中type只可能是一下两个值之一
-
clickCancel
用户点击了确认按钮 -
clickCancel
用户点击了取消按钮,也有可能是点击了背景遮罩,都认为是为无效的取消按钮
data 的值,就是用户出传进来的东西,用途广泛,可以是下一步函数的参数,也可以是区分多个弹框的逻辑
不带取消按钮的弹框
因为默认的弹框是带取消按钮的,所以只要给 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 发布博客
上一篇: 三星悄然修改Note 5触控笔插槽问题