From f26f29d84e0a68831a6af14dab3eec5500496d2e Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期三, 28 五月 2025 16:48:52 +0800
Subject: [PATCH] 初始化项目

---
 uview-ui/components/u-search/u-search.vue |  342 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 342 insertions(+), 0 deletions(-)

diff --git a/uview-ui/components/u-search/u-search.vue b/uview-ui/components/u-search/u-search.vue
new file mode 100644
index 0000000..206f661
--- /dev/null
+++ b/uview-ui/components/u-search/u-search.vue
@@ -0,0 +1,342 @@
+<template>
+	<view class="u-search" @tap="clickHandler" :style="{
+		margin: margin,
+	}">
+		<view
+			class="u-content"
+			:style="{
+				backgroundColor: bgColor,
+				borderRadius: shape == 'round' ? '100rpx' : '10rpx',
+				border: borderStyle,
+				height: height + 'rpx'
+			}"
+		>
+			<view class="u-icon-wrap">
+				<u-icon class="u-clear-icon" :size="30" :name="searchIcon" :color="searchIconColor ? searchIconColor : color"></u-icon>
+			</view>
+			<input
+				confirm-type="search"
+				@blur="blur"
+				:value="value"
+				@confirm="search"
+				@input="inputChange"
+				:disabled="disabled"
+				@focus="getFocus"
+				:focus="focus"
+				:maxlength="maxlength"
+				placeholder-class="u-placeholder-class"
+				:placeholder="placeholder"
+				:placeholder-style="`color: ${placeholderColor}`"
+				class="u-input"
+				type="text"
+				:style="[{
+					textAlign: inputAlign,
+					color: color,
+					backgroundColor: bgColor,
+				}, inputStyle]"
+			/>
+			<view class="u-close-wrap" v-if="keyword && clearabled && focused" @tap="clear">
+				<u-icon class="u-clear-icon" name="close-circle-fill" size="34" color="#c0c4cc"></u-icon>
+			</view>
+		</view>
+		<view :style="[actionStyle]" class="u-action" 
+			:class="[showActionBtn || show ? 'u-action-active' : '']" 
+			@tap.stop.prevent="custom"
+		>{{ actionText }}</view>
+	</view>
+</template>
+
+<script>
+/**
+ * search 鎼滅储妗�
+ * @description 鎼滅储缁勪欢锛岄泦鎴愪簡甯歌鎼滅储妗嗘墍闇�鍔熻兘锛岀敤鎴峰彲浠ヤ竴閿紩鍏ワ紝寮�绠卞嵆鐢ㄣ��
+ * @tutorial https://www.uviewui.com/components/search.html
+ * @property {String} shape 鎼滅储妗嗗舰鐘讹紝round-鍦嗗舰锛宻quare-鏂瑰舰锛堥粯璁ound锛�
+ * @property {String} bg-color 鎼滅储妗嗚儗鏅鑹诧紙榛樿#f2f2f2锛�
+ * @property {String} border-color 杈规棰滆壊锛岄厤缃簡棰滆壊锛屾墠浼氭湁杈规
+ * @property {String} placeholder 鍗犱綅鏂囧瓧鍐呭锛堥粯璁も�滆杈撳叆鍏抽敭瀛椻�濓級
+ * @property {Boolean} clearabled 鏄惁鍚敤娓呴櫎鎺т欢锛堥粯璁rue锛�
+ * @property {Boolean} focus 鏄惁鑷姩鑾峰緱鐒︾偣锛堥粯璁alse锛�
+ * @property {Boolean} show-action 鏄惁鏄剧ず鍙充晶鎺т欢锛堥粯璁rue锛�
+ * @property {String} action-text 鍙充晶鎺т欢鏂囧瓧锛堥粯璁も�滄悳绱⑩�濓級
+ * @property {Object} action-style 鍙充晶鎺т欢鐨勬牱寮忥紝瀵硅薄褰㈠紡
+ * @property {String} input-align 杈撳叆妗嗗唴瀹规按骞冲榻愭柟寮忥紙榛樿left锛�
+ * @property {Object} input-style 鑷畾涔夎緭鍏ユ鏍峰紡锛屽璞″舰寮�
+ * @property {Boolean} disabled 鏄惁鍚敤杈撳叆妗嗭紙榛樿false锛�
+ * @property {String} search-icon-color 鎼滅储鍥炬爣鐨勯鑹诧紝榛樿鍚岃緭鍏ユ瀛椾綋棰滆壊
+ * @property {String} color 杈撳叆妗嗗瓧浣撻鑹诧紙榛樿#606266锛�
+ * @property {String} placeholder-color placeholder鐨勯鑹诧紙榛樿#909399锛�
+ * @property {String} search-icon 杈撳叆妗嗗乏杈圭殑鍥炬爣锛屽彲浠ヤ负uView鍥炬爣鍚嶇О鎴栧浘鐗囪矾寰�
+ * @property {String} margin 缁勪欢涓庡叾浠栦笂涓嬪乏鍙冲厓绱犱箣闂寸殑璺濈锛屽甫鍗曚綅鐨勫瓧绗︿覆褰㈠紡锛屽"30rpx"
+ * @property {Boolean} animation 鏄惁寮�鍚姩鐢伙紝瑙佷笂鏂硅鏄庯紙榛樿false锛�
+ * @property {String} value 杈撳叆妗嗗垵濮嬪��
+ * @property {String | Number} maxlength 杈撳叆妗嗘渶澶ц兘杈撳叆鐨勯暱搴︼紝-1涓轰笉闄愬埗闀垮害
+ * @property {Boolean} input-style input杈撳叆妗嗙殑鏍峰紡锛屽彲浠ュ畾涔夋枃瀛楅鑹诧紝澶у皬绛夛紝瀵硅薄褰㈠紡
+ * @property {String | Number} height 杈撳叆妗嗛珮搴︼紝鍗曚綅rpx锛堥粯璁�64锛�
+ * @event {Function} change 杈撳叆妗嗗唴瀹瑰彂鐢熷彉鍖栨椂瑙﹀彂
+ * @event {Function} search 鐢ㄦ埛纭畾鎼滅储鏃惰Е鍙戯紝鐢ㄦ埛鎸夊洖杞﹂敭锛屾垨鑰呮墜鏈洪敭鐩樺彸涓嬭鐨�"鎼滅储"閿椂瑙﹀彂
+ * @event {Function} custom 鐢ㄦ埛鐐瑰嚮鍙充晶鎺т欢鏃惰Е鍙�
+ * @event {Function} clear 鐢ㄦ埛鐐瑰嚮娓呴櫎鎸夐挳鏃惰Е鍙�
+ * @example <u-search placeholder="鏃ョ収棣欑倝鐢熺传鐑�" v-model="keyword"></u-search>
+ */
+export default {
+	name: "u-search",
+	props: {
+		// 鎼滅储妗嗗舰鐘讹紝round-鍦嗗舰锛宻quare-鏂瑰舰
+		shape: {
+			type: String,
+			default: 'round'
+		},
+		// 鎼滅储妗嗚儗鏅壊锛岄粯璁ゅ��#f2f2f2
+		bgColor: {
+			type: String,
+			default: '#f2f2f2'
+		},
+		// 鍗犱綅鎻愮ず鏂囧瓧
+		placeholder: {
+			type: String,
+			default: '璇疯緭鍏ュ叧閿瓧'
+		},
+		// 鏄惁鍚敤娓呴櫎鎺т欢
+		clearabled: {
+			type: Boolean,
+			default: true
+		},
+		// 鏄惁鑷姩鑱氱劍
+		focus: {
+			type: Boolean,
+			default: false
+		},
+		// 鏄惁鍦ㄦ悳绱㈡鍙充晶鏄剧ず鍙栨秷鎸夐挳
+		showAction: {
+			type: Boolean,
+			default: true
+		},
+		// 鍙宠竟鎺т欢鐨勬牱寮�
+		actionStyle: {
+			type: Object,
+			default() {
+				return {};
+			}
+		},
+		// 鍙栨秷鎸夐挳鏂囧瓧
+		actionText: {
+			type: String,
+			default: '鎼滅储'
+		},
+		// 杈撳叆妗嗗唴瀹瑰榻愭柟寮忥紝鍙�夊�间负 left|center|right
+		inputAlign: {
+			type: String,
+			default: 'left'
+		},
+		// 鏄惁鍚敤杈撳叆妗�
+		disabled: {
+			type: Boolean,
+			default: false
+		},
+		// 寮�鍚痵howAction鏃讹紝鏄惁鍦╥nput鑾峰彇鐒︾偣鏃舵墠鏄剧ず
+		animation: {
+			type: Boolean,
+			default: false
+		},
+		// 杈规棰滆壊锛屽彧瑕侀厤缃簡棰滆壊锛屾墠浼氭湁杈规
+		borderColor: {
+			type: String,
+			default: 'none'
+		},
+		// 杈撳叆妗嗙殑鍒濆鍖栧唴瀹�
+		value: {
+			type: String,
+			default: ''
+		},
+		// 鎼滅储妗嗛珮搴︼紝鍗曚綅rpx
+		height: {
+			type: [Number, String],
+			default: 64
+		},
+		// input杈撳叆妗嗙殑鏍峰紡锛屽彲浠ュ畾涔夋枃瀛楅鑹诧紝澶у皬绛夛紝瀵硅薄褰㈠紡
+		inputStyle: {
+			type: Object,
+			default() {
+				return {}
+			}
+		},
+		// 杈撳叆妗嗘渶澶ц兘杈撳叆鐨勯暱搴︼紝-1涓轰笉闄愬埗闀垮害(鏉ヨ嚜uniapp鏂囨。)
+		maxlength: {
+			type: [Number, String],
+			default: '-1'
+		},
+		// 鎼滅储鍥炬爣鐨勯鑹诧紝榛樿鍚岃緭鍏ユ瀛椾綋棰滆壊
+		searchIconColor: {
+			type: String,
+			default: ''
+		},
+		// 杈撳叆妗嗗瓧浣撻鑹�
+		color: {
+			type: String,
+			default: '#606266'
+		},
+		// placeholder鐨勯鑹�
+		placeholderColor: {
+			type: String,
+			default: '#909399'
+		},
+		// 缁勪欢涓庡叾浠栦笂涓嬪乏鍙冲厓绱犱箣闂寸殑璺濈锛屽甫鍗曚綅鐨勫瓧绗︿覆褰㈠紡锛屽"30rpx"銆�"30rpx 20rpx"绛夊啓娉�
+		margin: {
+			type: String,
+			default: '0'
+		},
+		// 宸﹁竟杈撳叆妗嗙殑鍥炬爣锛屽彲浠ヤ负uView鍥炬爣鍚嶇О鎴栧浘鐗囪矾寰�
+		searchIcon: {
+			type: String,
+			default: 'search'
+		}
+	},
+	data() {
+		return {
+			keyword: '',
+			showClear: false, // 鏄惁鏄剧ず鍙宠竟鐨勬竻闄ゅ浘鏍�
+			show: false,
+			// 鏍囪input褰撳墠鐘舵�佹槸鍚﹀浜庤仛鐒︿腑锛屽鏋滄槸锛屾墠浼氭樉绀哄彸渚х殑娓呴櫎鎺т欢
+			focused: this.focus
+			// 缁戝畾杈撳叆妗嗙殑鍊�
+			// inputValue: this.value
+		};
+	},
+	watch: {
+		keyword(nVal) {
+			// 鍙屽悜缁戝畾鍊硷紝璁﹙-model缁戝畾鐨勫�煎弻鍚戝彉鍖�
+			this.$emit('input', nVal);
+			// 瑙﹀彂change浜嬩欢锛屼簨浠舵晥鏋滃拰v-model鍙屽悜缁戝畾鐨勬晥鏋滀竴鏍凤紝璁╃敤鎴峰涓�涓�夋嫨
+			this.$emit('change', nVal);
+		},
+		value: {
+			immediate: true,
+			handler(nVal) {
+				this.keyword = nVal;
+			}
+		}
+	},
+	computed: {
+		showActionBtn() {
+			if (!this.animation && this.showAction) return true;
+			else return false;
+		},
+		// 鏍峰紡锛屾牴鎹敤鎴蜂紶鍏ョ殑棰滆壊鍊肩敓鎴愶紝濡傛灉涓嶄紶鍏ワ紝榛樿涓簄one
+		borderStyle() {
+			if (this.borderColor) return `1px solid ${this.borderColor}`;
+			else return 'none';
+		},
+	},
+	methods: {
+		// 鐩墠HX2.6.9 v-model鍙屽悜缁戝畾鏃犳晥锛屾晠鐩戝惉input浜嬩欢鑾峰彇杈撳叆妗嗗唴瀹圭殑鍙樺寲
+		inputChange(e) {
+			this.keyword = e.detail.value;
+		},
+		// 娓呯┖杈撳叆
+		// 涔熷彲浠ヤ綔涓虹敤鎴烽�氳繃this.$refs褰㈠紡璋冪敤娓呯┖杈撳叆妗嗗唴瀹�
+		clear() {
+			this.keyword = '';
+			// 寤跺悗鍙戝嚭浜嬩欢锛岄伩鍏嶅湪鐖剁粍浠剁洃鍚琧lear浜嬩欢鏃讹紝value涓烘洿鏂板墠鐨勫��(涓嶄负绌�)
+			this.$nextTick(() => {
+				this.$emit('clear');
+			})
+		},
+		// 纭畾鎼滅储
+		search(e) {
+			this.$emit('search', e.detail.value);
+			try{
+				// 鏀惰捣閿洏
+				uni.hideKeyboard();
+			}catch(e){}
+		},
+		// 鐐瑰嚮鍙宠竟鑷畾涔夋寜閽殑浜嬩欢
+		custom() {
+			this.$emit('custom', this.keyword);
+			try{
+				// 鏀惰捣閿洏
+				uni.hideKeyboard();
+			}catch(e){}
+		},
+		// 鑾峰彇鐒︾偣
+		getFocus() {
+			this.focused = true;
+			// 寮�鍚彸渚ф悳绱㈡寜閽睍寮�鐨勫姩鐢绘晥鏋�
+			if (this.animation && this.showAction) this.show = true;
+			this.$emit('focus', this.keyword);
+		},
+		// 澶卞幓鐒︾偣
+		blur() {
+			// 鏈�寮�濮嬩娇鐢ㄧ殑鏄洃鍚浘鏍嘆touchstart浜嬩欢锛岃嚜浠巋x2.8.4鍚庯紝姝ゆ柟娉曞湪寰俊灏忕▼搴忓嚭閿�
+			// 杩欓噷鏀逛负鐩戝惉鐐瑰嚮浜嬩欢锛屾墜鐐瑰嚮娓呴櫎鍥炬爣鏃讹紝鍚屾椂涔熷彂鐢熶簡@blur浜嬩欢锛屽鑷村浘鏍囨秷澶辫�屾棤娉曠偣鍑伙紝杩欓噷鍋氫竴涓欢鏃�
+			setTimeout(() => {
+				this.focused = false;
+			}, 100)
+			this.show = false;
+			this.$emit('blur', this.keyword);
+		},
+		// 鐐瑰嚮鎼滅储妗嗭紝鍙湁disabled=true鏃舵墠鍙戝嚭浜嬩欢锛屽洜涓虹姝簡杈撳叆锛屾剰鍛崇潃鏄兂璺宠浆鐪熸鐨勬悳绱㈤〉
+		clickHandler() {
+			if(this.disabled) this.$emit('click');
+		}
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+@import "../../libs/css/style.components.scss";
+
+.u-search {
+	@include vue-flex;
+	align-items: center;
+	flex: 1;
+}
+
+.u-content {
+	@include vue-flex;
+	align-items: center;
+	padding: 0 18rpx;
+	flex: 1;
+}
+
+.u-clear-icon {
+	@include vue-flex;
+	align-items: center;
+}
+
+.u-input {
+	flex: 1;
+	font-size: 28rpx;
+	line-height: 1;
+	margin: 0 10rpx;
+	color: $u-tips-color;
+}
+
+.u-close-wrap {
+	width: 40rpx;
+	height: 100%;
+	@include vue-flex;
+	align-items: center;
+	justify-content: center;
+	border-radius: 50%;
+}
+
+.u-placeholder-class {
+	color: $u-tips-color;
+}
+
+.u-action {
+	font-size: 28rpx;
+	color: $u-main-color;
+	width: 0;
+	overflow: hidden;
+	transition: all 0.3s;
+	white-space: nowrap;
+	text-align: center;
+}
+
+.u-action-active {
+	width: 80rpx;
+	margin-left: 10rpx;
+}
+</style>

--
Gitblit v1.9.3