241 lines
5.5 KiB
Vue
241 lines
5.5 KiB
Vue
|
<template>
|
|||
|
<view
|
|||
|
v-if="visibleSync"
|
|||
|
class="tn-tips-class tn-tips"
|
|||
|
:class="[tipsClass]"
|
|||
|
:style="[tipsStyle]"
|
|||
|
>
|
|||
|
<view
|
|||
|
class="tn-tips__content"
|
|||
|
:class="[
|
|||
|
backgroundColorClass,
|
|||
|
fontColorClass
|
|||
|
]"
|
|||
|
:style="{
|
|||
|
backgroundColor: backgroundColorStyle,
|
|||
|
color: fontColorStyle
|
|||
|
}"
|
|||
|
>{{ msg }}</view>
|
|||
|
</view>
|
|||
|
</template>
|
|||
|
|
|||
|
<script>
|
|||
|
|
|||
|
export default {
|
|||
|
name: 'tn-tips',
|
|||
|
props: {
|
|||
|
// 层级
|
|||
|
zIndex: {
|
|||
|
type: Number,
|
|||
|
default: 0
|
|||
|
},
|
|||
|
// 提示框显示位置 top center bottom
|
|||
|
position: {
|
|||
|
type: String,
|
|||
|
default: 'top'
|
|||
|
},
|
|||
|
// 当位置设置为top的时候,设置距离顶部的距离
|
|||
|
top: {
|
|||
|
type: Number,
|
|||
|
default: 0
|
|||
|
}
|
|||
|
},
|
|||
|
computed: {
|
|||
|
tipsClass() {
|
|||
|
let clazz = ''
|
|||
|
switch (this.position) {
|
|||
|
case 'top':
|
|||
|
clazz += ' tn-tips--top'
|
|||
|
break
|
|||
|
case 'center':
|
|||
|
clazz += ' tn-tips--center'
|
|||
|
break
|
|||
|
case 'bottom':
|
|||
|
clazz += ' tn-tips--bottom'
|
|||
|
break
|
|||
|
default:
|
|||
|
clazz += ' tn-tips--top'
|
|||
|
}
|
|||
|
if (this.showTips) {
|
|||
|
clazz += ' tn-tips--show'
|
|||
|
}
|
|||
|
|
|||
|
return clazz
|
|||
|
},
|
|||
|
tipsStyle() {
|
|||
|
let style = {}
|
|||
|
if ((this.position === 'top' || this.position === '') && this.top) {
|
|||
|
style.top = this.top + 'px'
|
|||
|
}
|
|||
|
style.zIndex = (this.zIndex ? this.zIndex : this.$tn.zIndex.tips) + 1
|
|||
|
|
|||
|
return style
|
|||
|
},
|
|||
|
backgroundColorStyle() {
|
|||
|
return this.$tn.color.getBackgroundColorStyle(this.backgroundColor)
|
|||
|
},
|
|||
|
backgroundColorClass() {
|
|||
|
return this.$tn.color.getBackgroundColorInternalClass(this.backgroundColor)
|
|||
|
},
|
|||
|
fontColorStyle() {
|
|||
|
return this.$tn.color.getFontColorStyle(this.fontColor)
|
|||
|
},
|
|||
|
fontColorClass() {
|
|||
|
return this.$tn.color.getFontColorInternalClass(this.fontColor)
|
|||
|
},
|
|||
|
},
|
|||
|
data() {
|
|||
|
return {
|
|||
|
//关闭提示框定时器
|
|||
|
timer: null,
|
|||
|
// 是否渲染组件
|
|||
|
visibleSync: false,
|
|||
|
// 是否显示内容
|
|||
|
showTips: false,
|
|||
|
// 提示信息
|
|||
|
msg: '',
|
|||
|
// 背景颜色
|
|||
|
backgroundColor: '',
|
|||
|
// 字体颜色
|
|||
|
fontColor: ''
|
|||
|
}
|
|||
|
},
|
|||
|
methods: {
|
|||
|
show(options = {}) {
|
|||
|
const {
|
|||
|
duration = 2000,
|
|||
|
msg = '',
|
|||
|
backgroundColor = '',
|
|||
|
fontColor = ''
|
|||
|
} = options
|
|||
|
|
|||
|
if (this.timer !== null) clearTimeout(this.timer)
|
|||
|
|
|||
|
// 如果没有设置内容则不弹出
|
|||
|
if (!msg) {
|
|||
|
this._clearOptions()
|
|||
|
this.$emit('close')
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
this.msg = msg
|
|||
|
this.backgroundColor = backgroundColor || '#01BEFF'
|
|||
|
this.fontColor = fontColor || '#FFFFFF'
|
|||
|
|
|||
|
this.change('visibleSync', 'showTips', true)
|
|||
|
|
|||
|
this.timer = setTimeout(() => {
|
|||
|
clearTimeout(this.timer)
|
|||
|
this.timer = null
|
|||
|
this.change('showTips', 'visibleSync', false)
|
|||
|
}, duration)
|
|||
|
},
|
|||
|
|
|||
|
// 关闭时先通过动画隐藏弹窗和遮罩,再移除整个组件
|
|||
|
// 打开时,先渲染组件,延时一定时间再让遮罩和弹窗的动画起作用
|
|||
|
change(param1, param2, status) {
|
|||
|
this[param1] = status
|
|||
|
if (status) {
|
|||
|
// #ifdef H5 || MP
|
|||
|
this.timer = setTimeout(() => {
|
|||
|
this[param2] = status
|
|||
|
this.$emit(status ? 'open' : 'close')
|
|||
|
}, 50)
|
|||
|
// #endif
|
|||
|
// #ifndef H5 || MP
|
|||
|
this.$nextTick(() => {
|
|||
|
this[param2] = status
|
|||
|
this.$emit(status ? 'open' : 'close')
|
|||
|
})
|
|||
|
// #endif
|
|||
|
} else {
|
|||
|
this.timer = setTimeout(() => {
|
|||
|
this[param2] = status
|
|||
|
this.$emit(status ? 'open' : 'close')
|
|||
|
this._clearOptions()
|
|||
|
}, 300)
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
// 清除传递的参数
|
|||
|
_clearOptions() {
|
|||
|
this.msg = ''
|
|||
|
this.backgroundColor = ''
|
|||
|
this.fontColor = ''
|
|||
|
},
|
|||
|
}
|
|||
|
}
|
|||
|
</script>
|
|||
|
|
|||
|
<style lang="scss" scoped>
|
|||
|
|
|||
|
/*注意问题:
|
|||
|
1、fixed 元素宽度无法自适应,所以增加了子元素
|
|||
|
2、fixed 和 display冲突导致动画效果消失,暂时使用visibility替代
|
|||
|
*/
|
|||
|
.tn-tips {
|
|||
|
height: auto;
|
|||
|
position: fixed;
|
|||
|
box-sizing: border-box;
|
|||
|
display: flex;
|
|||
|
align-items: center;
|
|||
|
justify-content: center;
|
|||
|
transition: all 0.3s ease-in-out;
|
|||
|
opacity: 0;
|
|||
|
|
|||
|
&__content {
|
|||
|
word-wrap: break-word;
|
|||
|
word-break: break-all;
|
|||
|
width: 100%;
|
|||
|
height: auto;
|
|||
|
text-align: center;
|
|||
|
background-color: rgba(0, 0, 0, 0.7);
|
|||
|
color: #FFFFFF;
|
|||
|
}
|
|||
|
|
|||
|
&--top {
|
|||
|
width: 100% !important;
|
|||
|
/* padding: 18rpx 30rpx; */
|
|||
|
top: 0;
|
|||
|
left: 0;
|
|||
|
transform: translateY(-100%) translateZ(0);
|
|||
|
word-break: break-all;
|
|||
|
}
|
|||
|
|
|||
|
&--center {
|
|||
|
left: 50%;
|
|||
|
top: 50%;
|
|||
|
transform: translate(-50%, -50%);
|
|||
|
}
|
|||
|
|
|||
|
&--bottom {
|
|||
|
bottom: 120rpx;
|
|||
|
left: 50%;
|
|||
|
transform: translateX(-50%);
|
|||
|
}
|
|||
|
|
|||
|
&--center, &--bottom {
|
|||
|
.content {
|
|||
|
border-radius: 8rpx;
|
|||
|
padding: 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
&--center, &--bottom {
|
|||
|
.tn-tips__content {
|
|||
|
padding: 18rpx 30rpx !important;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
&--show {
|
|||
|
opacity: 1;
|
|||
|
|
|||
|
&.tn-tips--top {
|
|||
|
transform: translateY(0) translateZ(0) !important;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
</style>
|