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

241 lines
5.5 KiB
Vue
Raw Permalink Normal View History

2023-12-25 17:56:30 +08:00
<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>
/*
1fixed 元素宽度无法自适应所以增加了子元素
2fixed 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>