【PT.SCC实名制管理系统】24.10.01 -30天,考勤打卡小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

333 lines
10 KiB

<template>
<view class="uv-toast">
<uv-overlay :show="isShow && tmpConfig.overlay" :custom-style="overlayStyle"></uv-overlay>
<uv-transition :show="isShow" mode="fade" :custom-style="aniStyle">
<view
class="uv-toast__content"
ref="uvToastContent"
:style="[contentStyle]"
:class="['uv-type-' + tmpConfig.type, (tmpConfig.type === 'loading' || tmpConfig.loading) ? 'uv-toast__content--loading' : '']"
>
<uv-loading-icon
v-if="tmpConfig.type === 'loading'"
mode="circle"
color="rgb(255, 255, 255)"
inactiveColor="rgb(120, 120, 120)"
size="25"
></uv-loading-icon>
<uv-icon
v-else-if="tmpConfig.type !== 'defalut' && iconName"
:name="iconName"
size="17"
:color="tmpConfig.type"
:customStyle="iconStyle"
></uv-icon>
<uv-gap
v-if="tmpConfig.type === 'loading' || tmpConfig.loading"
height="12"
bgColor="transparent"
></uv-gap>
<text
class="uv-toast__content__text"
:class="['uv-toast__content__text--' + tmpConfig.type]"
style="max-width: 400rpx;"
>{{ tmpConfig.message }}</text>
</view>
</uv-transition>
</view>
</template>
<script>
import { hexToRgb } from '@/uni_modules/uv-ui-tools/libs/function/colorGradient.js'
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
// #ifdef APP-NVUE
const dom = uni.requireNativePlugin('dom')
// #endif
/**
* toast 消息提示
* @description 此组件表现形式类似uni的uni.showToastAPI,但也有不同的地方。
* @tutorial https://www.uvui.cn/components/toast.html
* @property {Boolean} loading 是否加载中 (默认 false )
* @property {String | Number} zIndex toast展示时的zIndex值 (默认 10090 )
* @property {String | Number} message 显示的文字内容
* @property {String} icon 图标,或者绝对路径的图片
* @property {String} type 主题类型 (默认 default)
* @property {Boolean} overlay 是否显示透明遮罩,防止点击穿透 (默认 false )
* @property {String} position 位置 (默认 'center' )
* @property {Object} params 跳转的参数
* @property {String | Number} duration 展示时间,单位ms (默认 2000 )
* @property {Function} complete 执行完后的回调函数
*
* @event {Function} show 显示toast,如需一进入页面就显示toast,请在onReady生命周期调用
* @example <uv-toast ref="uvToastRef" />
*/
export default {
name: 'uv-toast',
mixins: [mpMixin, mixin],
data() {
return {
isShow: false,
timer: null, // 定时器
config: {
message: '', // 显示文本
type: '', // 主题类型,primary,success,error,warning,black
duration: 2000, // 显示的时间,毫秒
icon: true, // 显示的图标
position: 'center', // toast出现的位置
complete: null, // 执行完后的回调函数
overlay: true, // 是否防止触摸穿透
loading: false ,// 是否加载中状态
zIndex: 10090 //弹出的层级
},
tmpConfig: {}, // 将用户配置和内置配置合并后的临时配置变量
rect: {},
opacity: 0
}
},
computed: {
iconName() {
// 只有不为none,并且type为error|warning|succes|info时候,才显示图标
if (!this.tmpConfig.icon || this.tmpConfig.icon == 'none') {
return '';
}
if (['error', 'warning', 'success', 'primary'].includes(this.tmpConfig.type)) {
return this.$uv.type2icon(this.tmpConfig.type)
} else {
return ''
}
},
overlayStyle() {
const style = {
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
zIndex: this.tmpConfig.zIndex
}
// 将遮罩设置为100%透明度,避免出现灰色背景
style.backgroundColor = 'rgba(0, 0, 0, 0)'
return style
},
iconStyle() {
const style = {}
// 图标需要一个右边距,以跟右边的文字有隔开的距离
style.marginRight = '4px'
// #ifdef APP-NVUE
// iOSAPP下,图标有1px的向下偏移,这里进行修正
if (this.$uv.os() === 'ios') {
style.marginTop = '-1px'
}
// #endif
return style
},
aniStyle() {
const style = {
position: 'fixed',
zIndex: this.tmpConfig.zIndex
}
return style
},
// 内容盒子的样式
contentStyle() {
const { windowWidth, windowHeight } = this.$uv.sys();
const style = {
position: 'fixed',
top: '50%',
left: '50%',
// #ifdef APP-NVUE
opacity: this.opacity
// #endif
};
let value = 0
// #ifndef APP-NVUE
// 根据top和bottom,对Y轴进行窗体高度的百分比偏移
if (this.tmpConfig.position === 'top') {
style.top = '25%'
} else if (this.tmpConfig.position === 'bottom') {
style.top = '75%'
} else {
value = '-50%'
}
style.transform = `translate(-50%,${value})`
// #endif
// #ifdef APP-NVUE
const { width = 0, height = 0 } = this.rect ? this.rect : {};
if (width && height) {
style.left = `${windowWidth*0.5 - width/2}px`
if (this.tmpConfig.position === 'top') {
style.top = `${windowHeight*0.5- height/2 - windowHeight*0.25}px`
} else if (this.tmpConfig.position === 'bottom') {
style.top = `${windowHeight*0.5- height/2 + windowHeight*0.25}px`
} else {
style.top = `${windowHeight*0.5- height/2}px`
}
}
// #endif
return style
}
},
created() {
// 通过主题的形式调用toast,批量生成方法函数
['primary', 'success', 'error', 'warning', 'default', 'loading'].map(item => {
this[item] = message => this.show({
type: item,
message
})
})
},
methods: {
// 显示toast组件,由父组件通过this.$refs.xxx.show(options)形式调用
show(options) {
// 不将结果合并到this.config变量,避免多次调用uv-toast,前后的配置造成混乱
this.tmpConfig = this.$uv.deepMerge(this.config, options)
// 清除定时器
this.clearTimer()
this.isShow = true
//#ifdef APP-NVUE
this.$nextTick(() => {
this.$uv.sleep(100).then(async res => {
this.rect = await this.queryRect();
this.$nextTick(() => {
this.opacity = 1;
})
})
})
// #endif
this.timer = setTimeout(() => {
// 倒计时结束,清除定时器,隐藏toast组件
this.clearTimer()
// 判断是否存在callback方法,如果存在就执行
typeof(this.tmpConfig.complete) === 'function' && this.tmpConfig.complete()
}, this.tmpConfig.duration)
},
// 查询内容高度
queryRect() {
return new Promise(resolve => {
const ref = this.$refs['uvToastContent'];
dom.getComponentRect(ref, res => {
resolve(res.size)
})
})
},
// 隐藏toast组件,由父组件通过this.$refs.xxx.hide()形式调用
hide() {
this.clearTimer()
},
clearTimer() {
// #ifdef APP-NVUE
this.opacity = 0;
// #endif
this.isShow = false
// 清除定时器
clearTimeout(this.timer)
this.timer = null
}
},
// #ifdef VUE2
beforeDestroy() {
this.clearTimer()
},
// #endif
// #ifdef VUE3
unmounted() {
this.clearTimer()
}
// #endif
}
</script>
<style lang="scss" scoped>
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
@import '@/uni_modules/uv-ui-tools/libs/css/color.scss';
$uv-toast-color: #fff !default;
$uv-toast-border-radius: 4px !default;
$uv-toast-border-background-color: #585858 !default;
$uv-toast-border-font-size: 14px !default;
$uv-toast-border-padding: 12px 20px !default;
$uv-toast-loading-border-padding: 20px 20px !default;
$uv-toast-content-text-color: #fff !default;
$uv-toast-content-text-font-size: 15px !default;
$uv-toast-uv-icon: 10rpx !default;
$uv-toast-uv-type-primary-color: $uv-primary !default;
$uv-toast-uv-type-primary-background-color: #ecf5ff !default;
$uv-toast-uv-type-primary-border-color: rgb(215, 234, 254) !default;
$uv-toast-uv-type-primary-border-width: 1px !default;
$uv-toast-uv-type-success-color: $uv-success !default;
$uv-toast-uv-type-success-background-color: #dbf1e1 !default;
$uv-toast-uv-type-success-border-color: #BEF5C8 !default;
$uv-toast-uv-type-success-border-width: 1px !default;
$uv-toast-uv-type-error-color: $uv-error !default;
$uv-toast-uv-type-error-background-color: #fef0f0 !default;
$uv-toast-uv-type-error-border-color: #fde2e2 !default;
$uv-toast-uv-type-error-border-width: 1px !default;
$uv-toast-uv-type-warning-color: $uv-warning !default;
$uv-toast-uv-type-warning-background-color: #fdf6ec !default;
$uv-toast-uv-type-warning-border-color: #faecd8 !default;
$uv-toast-uv-type-warning-border-width: 1px !default;
$uv-toast-uv-type-default-color: #fff !default;
$uv-toast-uv-type-default-background-color: #585858 !default;
.uv-toast {
&__content {
@include flex;
padding: $uv-toast-border-padding;
border-radius: $uv-toast-border-radius;
background-color: $uv-toast-border-background-color;
color: $uv-toast-color;
align-items: center;
/* #ifndef APP-NVUE */
max-width: 600rpx;
/* #endif */
position: relative;
&--loading {
flex-direction: column;
padding: $uv-toast-loading-border-padding;
}
&__text {
color: $uv-toast-content-text-color;
font-size: $uv-toast-content-text-font-size;
line-height: $uv-toast-content-text-font-size;
&--default {
color: $uv-toast-content-text-color;
}
&--error {
color: $uv-error;
}
&--primary {
color: $uv-primary;
}
&--success {
color: $uv-success;
}
&--warning {
color: $uv-warning;
}
}
}
}
.uv-type-primary {
color: $uv-toast-uv-type-primary-color;
background-color: $uv-toast-uv-type-primary-background-color;
border-color: $uv-toast-uv-type-primary-border-color;
border-width: $uv-toast-uv-type-primary-border-width;
}
.uv-type-success {
color: $uv-toast-uv-type-success-color;
background-color: $uv-toast-uv-type-success-background-color;
border-color: $uv-toast-uv-type-success-border-color;
border-width: 1px;
}
.uv-type-error {
color: $uv-toast-uv-type-error-color;
background-color: $uv-toast-uv-type-error-background-color;
border-color: $uv-toast-uv-type-error-border-color;
border-width: $uv-toast-uv-type-error-border-width;
}
.uv-type-warning {
color: $uv-toast-uv-type-warning-color;
background-color: $uv-toast-uv-type-warning-background-color;
border-color: $uv-toast-uv-type-warning-border-color;
border-width: 1px;
}
.uv-type-default {
color: $uv-toast-uv-type-default-color;
background-color: $uv-toast-uv-type-default-background-color;
}
</style>