forked from angelo/web-retail-h5
				
			
		
			
	
	
		
			212 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Vue
		
	
	
	
		
		
			
		
	
	
			212 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Vue
		
	
	
	
|  | <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> |