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.
211 lines
5.9 KiB
211 lines
5.9 KiB
<template> |
|
<u-transition |
|
mode="slide-down" |
|
:customStyle="containerStyle" |
|
:show="open" |
|
> |
|
<view |
|
class="u-notify" |
|
:class="[`u-notify--${tmpConfig.type}`]" |
|
:style="[backgroundColor, $u.addStyle(customStyle)]" |
|
> |
|
<u-status-bar v-if="tmpConfig.safeAreaInsetTop"></u-status-bar> |
|
<view class="u-notify__warpper"> |
|
<slot name="icon"> |
|
<u-icon |
|
v-if="['success', 'warning', 'error'].includes(tmpConfig.type)" |
|
:name="tmpConfig.icon" |
|
:color="tmpConfig.color" |
|
:size="1.3 * tmpConfig.fontSize" |
|
:customStyle="{marginRight: '4px'}" |
|
></u-icon> |
|
</slot> |
|
<text |
|
class="u-notify__warpper__text" |
|
:style="{ |
|
fontSize: $u.addUnit(tmpConfig.fontSize), |
|
color: tmpConfig.color |
|
}" |
|
>{{ tmpConfig.message }}</text> |
|
</view> |
|
</view> |
|
</u-transition> |
|
</template> |
|
|
|
<script> |
|
import props from './props.js'; |
|
/** |
|
* notify 顶部提示 |
|
* @description 该组件一般用于页面顶部向下滑出一个提示,尔后自动收起的场景 |
|
* @tutorial |
|
* @property {String | Number} top 到顶部的距离 ( 默认 0 ) |
|
* @property {String} type 主题,primary,success,warning,error ( 默认 'primary' ) |
|
* @property {String} color 字体颜色 ( 默认 '#ffffff' ) |
|
* @property {String} bgColor 背景颜色 |
|
* @property {String} message 展示的文字内容 |
|
* @property {String | Number} duration 展示时长,为0时不消失,单位ms ( 默认 3000 ) |
|
* @property {String | Number} fontSize 字体大小 ( 默认 15 ) |
|
* @property {Boolean} safeAreaInsetTop 是否留出顶部安全距离(状态栏高度) ( 默认 false ) |
|
* @property {Object} customStyle 组件的样式,对象形式 |
|
* @event {Function} open 开启组件时调用的函数 |
|
* @event {Function} close 关闭组件式调用的函数 |
|
* @example <u-notify message="Hi uView"></u-notify> |
|
*/ |
|
export default { |
|
name: 'u-notify', |
|
mixins: [uni.$u.mpMixin, uni.$u.mixin,props], |
|
data() { |
|
return { |
|
// 是否展示组件 |
|
open: false, |
|
timer: null, |
|
config: { |
|
// 到顶部的距离 |
|
top: uni.$u.props.notify.top, |
|
// type主题,primary,success,warning,error |
|
type: uni.$u.props.notify.type, |
|
// 字体颜色 |
|
color: uni.$u.props.notify.color, |
|
// 背景颜色 |
|
bgColor: uni.$u.props.notify.bgColor, |
|
// 展示的文字内容 |
|
message: uni.$u.props.notify.message, |
|
// 展示时长,为0时不消失,单位ms |
|
duration: uni.$u.props.notify.duration, |
|
// 字体大小 |
|
fontSize: uni.$u.props.notify.fontSize, |
|
// 是否留出顶部安全距离(状态栏高度) |
|
safeAreaInsetTop: uni.$u.props.notify.safeAreaInsetTop |
|
}, |
|
// 合并后的配置,避免多次调用组件后,可能会复用之前使用的配置参数 |
|
tmpConfig: {} |
|
} |
|
}, |
|
computed: { |
|
containerStyle() { |
|
let top = 0 |
|
if (this.tmpConfig.top === 0) { |
|
// #ifdef H5 |
|
// H5端,导航栏为普通元素,需要将组件移动到导航栏的下边沿 |
|
// H5的导航栏高度为44px |
|
top = 44 |
|
// #endif |
|
} |
|
const style = { |
|
top: uni.$u.addUnit(this.tmpConfig.top === 0 ? top : this.tmpConfig.top), |
|
// 因为组件底层为u-transition组件,必须将其设置为fixed定位 |
|
// 让其出现在导航栏底部 |
|
position: 'fixed', |
|
left: 0, |
|
right: 0, |
|
zIndex: 10076 |
|
} |
|
return style |
|
}, |
|
// 组件背景颜色 |
|
backgroundColor() { |
|
const style = {} |
|
if (this.tmpConfig.bgColor) { |
|
style.backgroundColor = this.tmpConfig.bgColor |
|
} |
|
return style |
|
}, |
|
// 默认主题下的图标 |
|
icon() { |
|
let icon |
|
if (this.tmpConfig.type === 'success') { |
|
icon = 'checkmark-circle' |
|
} else if (this.tmpConfig.type === 'error') { |
|
icon = 'close-circle' |
|
} else if (this.tmpConfig.type === 'warning') { |
|
icon = 'error-circle' |
|
} |
|
return icon |
|
} |
|
}, |
|
created() { |
|
// 通过主题的形式调用toast,批量生成方法函数 |
|
['primary', 'success', 'error', 'warning'].map(item => { |
|
this[item] = message => this.show({ |
|
type: item, |
|
message |
|
}) |
|
}) |
|
}, |
|
methods: { |
|
show(options) { |
|
// 不将结果合并到this.config变量,避免多次调用u-toast,前后的配置造成混乱 |
|
this.tmpConfig = uni.$u.deepMerge(this.config, options) |
|
// 任何定时器初始化之前,都要执行清除操作,否则可能会造成混乱 |
|
this.clearTimer() |
|
this.open = true |
|
if (this.tmpConfig.duration > 0) { |
|
this.timer = setTimeout(() => { |
|
this.open = false |
|
// 倒计时结束,清除定时器,隐藏toast组件 |
|
this.clearTimer() |
|
// 判断是否存在callback方法,如果存在就执行 |
|
typeof(this.tmpConfig.complete) === 'function' && this.tmpConfig.complete() |
|
}, this.tmpConfig.duration) |
|
} |
|
}, |
|
// 关闭notify |
|
close() { |
|
this.clearTimer() |
|
}, |
|
clearTimer() { |
|
this.open = false |
|
// 清除定时器 |
|
clearTimeout(this.timer) |
|
this.timer = null |
|
} |
|
}, |
|
beforeDestroy() { |
|
this.clearTimer() |
|
} |
|
} |
|
</script> |
|
|
|
<style lang="scss" scoped> |
|
@import "../../libs/css/components.scss"; |
|
|
|
$u-notify-padding: 8px 10px !default; |
|
$u-notify-text-font-size: 15px !default; |
|
$u-notify-primary-bgColor: $u-primary !default; |
|
$u-notify-success-bgColor: $u-success !default; |
|
$u-notify-error-bgColor: $u-error !default; |
|
$u-notify-warning-bgColor: $u-warning !default; |
|
|
|
|
|
.u-notify { |
|
padding: $u-notify-padding; |
|
|
|
&__warpper { |
|
@include flex; |
|
align-items: center; |
|
text-align: center; |
|
justify-content: center; |
|
|
|
&__text { |
|
font-size: $u-notify-text-font-size; |
|
text-align: center; |
|
} |
|
} |
|
|
|
&--primary { |
|
background-color: $u-notify-primary-bgColor; |
|
} |
|
|
|
&--success { |
|
background-color: $u-notify-success-bgColor; |
|
} |
|
|
|
&--error { |
|
background-color: $u-notify-error-bgColor; |
|
} |
|
|
|
&--warning { |
|
background-color: $u-notify-warning-bgColor; |
|
} |
|
} |
|
</style>
|
|
|