yunshangxie/tuniao-ui/components/tn-tips/tn-tips.vue

241 lines
5.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>