From d1448cb0ef10f358bb7bddb4e1ec268515e0b787 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 15 七月 2025 11:46:57 +0800
Subject: [PATCH] 项目初始化

---
 uni_modules/uview-ui/components/u-image/u-image.vue |  232 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 232 insertions(+), 0 deletions(-)

diff --git a/uni_modules/uview-ui/components/u-image/u-image.vue b/uni_modules/uview-ui/components/u-image/u-image.vue
new file mode 100644
index 0000000..d7105c2
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-image/u-image.vue
@@ -0,0 +1,232 @@
+<template>
+	<u-transition
+		mode="fade"
+		:show="show"
+		:duration="fade ? 1000 : 0"
+	>
+		<view
+			class="u-image"
+			@tap="onClick"
+			:style="[wrapStyle, backgroundStyle]"
+		>
+			<image
+				v-if="!isError"
+				:src="src"
+				:mode="mode"
+				@error="onErrorHandler"
+				@load="onLoadHandler"
+				:show-menu-by-longpress="showMenuByLongpress"
+				:lazy-load="lazyLoad"
+				class="u-image__image"
+				:style="{
+					borderRadius: shape == 'circle' ? '10000px' : $u.addUnit(radius),
+					width: $u.addUnit(width),
+					height: $u.addUnit(height)
+				}"
+			></image>
+			<view
+				v-if="showLoading && loading"
+				class="u-image__loading"
+				:style="{
+					borderRadius: shape == 'circle' ? '50%' : $u.addUnit(radius),
+					backgroundColor: this.bgColor,
+					width: $u.addUnit(width),
+					height: $u.addUnit(height)
+				}"
+			>
+				<slot name="loading">
+					<u-icon
+						:name="loadingIcon"
+						:width="width"
+						:height="height"
+					></u-icon>
+				</slot>
+			</view>
+			<view
+				v-if="showError && isError && !loading"
+				class="u-image__error"
+				:style="{
+					borderRadius: shape == 'circle' ? '50%' : $u.addUnit(radius),
+					width: $u.addUnit(width),
+					height: $u.addUnit(height)
+				}"
+			>
+				<slot name="error">
+					<u-icon
+						:name="errorIcon"
+						:width="width"
+						:height="height"
+					></u-icon>
+				</slot>
+			</view>
+		</view>
+	</u-transition>
+</template>
+
+<script>
+	import props from './props.js';
+	/**
+	 * Image 鍥剧墖
+	 * @description 姝ょ粍浠朵负uni-app鐨刬mage缁勪欢鐨勫姞寮虹増锛屽湪缁ф壙浜嗗師鏈夊姛鑳藉锛岃繕鏀寔娣″叆鍔ㄧ敾銆佸姞杞戒腑銆佸姞杞藉け璐ユ彁绀恒�佸渾瑙掑�煎拰褰㈢姸绛夈��
+	 * @tutorial https://uviewui.com/components/image.html
+	 * @property {String}			src 				鍥剧墖鍦板潃
+	 * @property {String}			mode 				瑁佸壀妯″紡锛岃瀹樼綉璇存槑 锛堥粯璁� 'aspectFill' 锛�
+	 * @property {String | Number}	width 				瀹藉害锛屽崟浣嶄换鎰忥紝濡傛灉涓烘暟鍊硷紝鍒欎负px鍗曚綅 锛堥粯璁� '300' 锛�
+	 * @property {String | Number}	height 				楂樺害锛屽崟浣嶄换鎰忥紝濡傛灉涓烘暟鍊硷紝鍒欎负px鍗曚綅 锛堥粯璁� '225' 锛�
+	 * @property {String}			shape 				鍥剧墖褰㈢姸锛宑ircle-鍦嗗舰锛宻quare-鏂瑰舰 锛堥粯璁� 'square' 锛�
+	 * @property {String | Number}	radius		 		鍦嗚鍊硷紝鍗曚綅浠绘剰锛屽鏋滀负鏁板�硷紝鍒欎负px鍗曚綅 锛堥粯璁� 0 锛�
+	 * @property {Boolean}			lazyLoad			鏄惁鎳掑姞杞斤紝浠呭井淇″皬绋嬪簭銆丄pp銆佺櫨搴﹀皬绋嬪簭銆佸瓧鑺傝烦鍔ㄥ皬绋嬪簭鏈夋晥 锛堥粯璁� true 锛�
+	 * @property {Boolean}			showMenuByLongpress	鏄惁寮�鍚暱鎸夊浘鐗囨樉绀鸿瘑鍒皬绋嬪簭鐮佽彍鍗曪紝浠呭井淇″皬绋嬪簭鏈夋晥 锛堥粯璁� true 锛�
+	 * @property {String}			loadingIcon 		鍔犺浇涓殑鍥炬爣锛屾垨鑰呭皬鍥剧墖 锛堥粯璁� 'photo' 锛�
+	 * @property {String}			errorIcon 			鍔犺浇澶辫触鐨勫浘鏍囷紝鎴栬�呭皬鍥剧墖 锛堥粯璁� 'error-circle' 锛�
+	 * @property {Boolean}			showLoading 		鏄惁鏄剧ず鍔犺浇涓殑鍥炬爣鎴栬�呰嚜瀹氫箟鐨剆lot 锛堥粯璁� true 锛�
+	 * @property {Boolean}			showError 			鏄惁鏄剧ず鍔犺浇閿欒鐨勫浘鏍囨垨鑰呰嚜瀹氫箟鐨剆lot 锛堥粯璁� true 锛�
+	 * @property {Boolean}			fade 				鏄惁闇�瑕佹贰鍏ユ晥鏋� 锛堥粯璁� true 锛�
+	 * @property {Boolean}			webp 				鍙敮鎸佺綉缁滆祫婧愶紝鍙寰俊灏忕▼搴忔湁鏁� 锛堥粯璁� false 锛�
+	 * @property {String | Number}	duration 			鎼厤fade鍙傛暟鐨勮繃娓℃椂闂达紝鍗曚綅ms 锛堥粯璁� 500 锛�
+	 * @property {String}			bgColor 			鑳屾櫙棰滆壊锛岀敤浜庢繁鑹查〉闈㈠姞杞藉浘鐗囨椂锛屼负浜嗗拰鑳屾櫙鑹茶瀺鍚�  (榛樿 '#f3f4f6' )
+	 * @property {Object}			customStyle  		瀹氫箟闇�瑕佺敤鍒扮殑澶栭儴鏍峰紡
+	 * @event {Function}	click	鐐瑰嚮鍥剧墖鏃惰Е鍙�
+	 * @event {Function}	error	鍥剧墖鍔犺浇澶辫触鏃惰Е鍙�
+	 * @event {Function} load 鍥剧墖鍔犺浇鎴愬姛鏃惰Е鍙�
+	 * @example <u-image width="100%" height="300px" :src="src"></u-image>
+	 */
+	export default {
+		name: 'u-image',
+		mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+		data() {
+			return {
+				// 鍥剧墖鏄惁鍔犺浇閿欒锛屽鏋滄槸锛屽垯鏄剧ず閿欒鍗犱綅鍥�
+				isError: false,
+				// 鍒濆鍖栫粍浠舵椂锛岄粯璁や负鍔犺浇涓姸鎬�
+				loading: true,
+				// 涓嶉�忔槑搴︼紝涓轰簡瀹炵幇娣″叆娣″嚭鐨勬晥鏋�
+				opacity: 1,
+				// 杩囨浮鏃堕棿锛屽洜涓簆rops鐨勫�兼棤娉曚慨鏀癸紝鏁呴渶瑕佷竴涓腑闂村��
+				durationTime: this.duration,
+				// 鍥剧墖鍔犺浇瀹屾垚鏃讹紝鍘绘帀鑳屾櫙棰滆壊锛屽洜涓哄鏋滄槸png鍥剧墖锛屽氨浼氭樉绀虹伆鑹茬殑鑳屾櫙
+				backgroundStyle: {},
+				// 鐢ㄤ簬fade妯″紡鐨勬帶鍒剁粍浠舵樉绀轰笌鍚�
+				show: false
+			};
+		},
+		watch: {
+			src: {
+				immediate: true,
+				handler(n) {
+					if (!n) {
+						// 濡傛灉浼犲叆null鎴栬��''锛屾垨鑰協alse锛屾垨鑰卽ndefined锛屾爣璁颁负閿欒鐘舵��
+						this.isError = true
+						
+					} else {
+						this.isError = false;
+						this.loading = true;
+					}
+				}
+			}
+		},
+		computed: {
+			wrapStyle() {
+				let style = {};
+				// 閫氳繃璋冪敤addUnit()鏂规硶锛屽鏋滄湁鍗曚綅锛屽鐧惧垎姣旓紝px鍗曚綅绛夛紝鐩存帴杩斿洖锛屽鏋滄槸绾补鐨勬暟鍊硷紝鍒欏姞涓妑px鍗曚綅
+				style.width = this.$u.addUnit(this.width);
+				style.height = this.$u.addUnit(this.height);
+				// 濡傛灉鏄樉绀哄渾褰紝璁剧疆涓�涓緢澶氱殑鍗婂緞鍊煎嵆鍙�
+				style.borderRadius = this.shape == 'circle' ? '10000px' : uni.$u.addUnit(this.radius)
+				// 濡傛灉璁剧疆鍦嗚锛屽繀椤昏鏈塰idden锛屽惁鍒欏彲鑳藉渾瑙掓棤鏁�
+				style.overflow = this.borderRadius > 0 ? 'hidden' : 'visible'
+				// if (this.fade) {
+				// 	style.opacity = this.opacity
+				// 	// nvue涓嬶紝杩欏嚑涓睘鎬у繀椤昏鍒嗗紑鍐�
+				// 	style.transitionDuration = `${this.durationTime}ms`
+				// 	style.transitionTimingFunction = 'ease-in-out'
+				// 	style.transitionProperty = 'opacity'
+				// }
+				return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle));
+
+			}
+		},
+		mounted() {
+			this.show = true
+		},
+		methods: {
+			// 鐐瑰嚮鍥剧墖
+			onClick() {
+				this.$emit('click')
+			},
+			// 鍥剧墖鍔犺浇澶辫触
+			onErrorHandler(err) {
+				this.loading = false
+				this.isError = true
+				this.$emit('error', err)
+			},
+			// 鍥剧墖鍔犺浇瀹屾垚锛屾爣璁發oading缁撴潫
+			onLoadHandler() {
+				this.loading = false
+				this.isError = false
+				this.$emit('load')
+				this.removeBgColor()
+				// 濡傛灉涓嶉渶瑕佸姩鐢绘晥鏋滐紝灏变笉鎵ц涓嬫柟浠g爜锛屽悓鏃剁Щ闄ゅ姞杞芥椂鐨勮儗鏅鑹�
+				// 鍚﹀垯鏃犻渶fade鏁堟灉鏃讹紝png鍥剧墖渚濈劧鑳界湅鍒颁笅鏂圭殑鑳屾櫙鑹�
+				// if (!this.fade) return this.removeBgColor();
+				// // 鍘熸潵opacity涓�1(涓嶉�忔槑锛屾槸涓轰簡鏄剧ず鍗犱綅鍥�)锛屾敼鎴�0(閫忔槑锛屾剰鍛崇潃璇ュ厓绱犳樉绀虹殑鏄儗鏅鑹诧紝榛樿鐨勭伆鑹�)锛屽啀鏀规垚1锛屾槸涓轰簡鑾峰緱杩囨浮鏁堟灉
+				// this.opacity = 0;
+				// // 杩欓噷璁剧疆涓�0锛屾槸涓轰簡鍥剧墖灞曠ず鍒拌儗鏅叏閫忔槑杩欎釜杩囩▼鏃堕棿涓�0锛屽欢鏃朵箣鍚庡欢鏃朵箣鍚庨噸鏂拌缃负duration锛屾槸涓轰簡鑾峰緱鑳屾櫙閫忔槑(鐏拌壊)
+				// // 鍒板浘鐗囧睍绀虹殑杩囩▼涓殑娣″叆鏁堟灉
+				// this.durationTime = 0;
+				// // 寤舵椂50ms锛屽惁鍒欏湪娴忚鍣℉5锛岃繃娓℃晥鏋滄棤鏁�
+				// setTimeout(() => {
+				// 	this.durationTime = this.duration;
+				// 	this.opacity = 1;
+				// 	setTimeout(() => {
+				// 		this.removeBgColor();
+				// 	}, this.durationTime);
+				// }, 50);
+			},
+			// 绉婚櫎鍥剧墖鐨勮儗鏅壊
+			removeBgColor() {
+				// 娣″叆鍔ㄧ敾杩囨浮瀹屾垚鍚庯紝灏嗚儗鏅缃负閫忔槑鑹诧紝鍚﹀垯png鍥剧墖浼氱湅鍒扮伆鑹茬殑鑳屾櫙
+				this.backgroundStyle = {
+					backgroundColor: 'transparent'
+				};
+			}
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	@import '../../libs/css/components.scss';
+
+	$u-image-error-top:0px !default;
+	$u-image-error-left:0px !default;
+	$u-image-error-width:100% !default;
+	$u-image-error-hight:100% !default;
+	$u-image-error-background-color:$u-bg-color !default;
+	$u-image-error-color:$u-tips-color !default;
+	$u-image-error-font-size: 46rpx !default;
+
+	.u-image {
+		position: relative;
+		transition: opacity 0.5s ease-in-out;
+
+		&__image {
+			width: 100%;
+			height: 100%;
+		}
+
+		&__loading,
+		&__error {
+			position: absolute;
+			top: $u-image-error-top;
+			left: $u-image-error-left;
+			width: $u-image-error-width;
+			height: $u-image-error-hight;
+			@include flex;
+			align-items: center;
+			justify-content: center;
+			background-color: $u-image-error-background-color;
+			color: $u-image-error-color;
+			font-size: $u-image-error-font-size;
+		}
+	}
+</style>

--
Gitblit v1.9.3