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-rate/u-rate.vue |  275 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 275 insertions(+), 0 deletions(-)

diff --git a/uview-ui/components/u-rate/u-rate.vue b/uview-ui/components/u-rate/u-rate.vue
new file mode 100644
index 0000000..17eb3a8
--- /dev/null
+++ b/uview-ui/components/u-rate/u-rate.vue
@@ -0,0 +1,275 @@
+<template>
+	<view class="u-rate" :id="elId" @touchmove.stop.prevent="touchMove">
+		<view class="u-star-wrap" v-for="(item, index) in count" :key="index" :class="[elClass]">
+			<u-icon
+				:name="activeIndex > index ? elActiveIcon : inactiveIcon"
+				@click="click(index + 1, $event)"
+				:color="activeIndex > index ? elActiveColor : inactiveColor"
+				:custom-style="{
+					fontSize: size + 'rpx',
+					padding: `0 ${gutter / 2 + 'rpx'}`
+				}"
+				:custom-prefix="customPrefix"
+				:show-decimal-icon="showDecimalIcon(index)"
+				:percent="decimal"
+				:inactive-color="inactiveColor"
+			></u-icon>
+		</view>
+	</view>
+</template>
+
+<script>/**
+ * rate 璇勫垎
+ * @description 璇ョ粍浠朵竴鑸敤浜庢弧鎰忓害璋冩煡锛屾槦鍨嬭瘎鍒嗙殑鍦烘櫙
+ * @tutorial https://www.uviewui.com/components/rate.html
+ * @property {String Number} count 鏈�澶氬彲閫夌殑鏄熸槦鏁伴噺锛堥粯璁�5锛�
+ * @property {String Number} current 榛樿閫変腑鐨勬槦鏄熸暟閲忥紙榛樿0锛�
+ * @property {Boolean} disabled 鏄惁绂佹鐢ㄦ埛鎿嶄綔锛堥粯璁alse锛�
+ * @property {String Number} size 鏄熸槦鐨勫ぇ灏忥紝鍗曚綅rpx锛堥粯璁�32锛�
+ * @property {String} inactive-color 鏈�変腑鏄熸槦鐨勯鑹诧紙榛樿#b2b2b2锛�
+ * @property {String} active-color 閫変腑鐨勬槦鏄熼鑹诧紙榛樿#FA3534锛�
+ * @property {String} active-icon 閫変腑鏃剁殑鍥炬爣鍚嶏紝鍙兘涓簎View鐨勫唴缃浘鏍囷紙榛樿star-fill锛�
+ * @property {String} inactive-icon 鏈�変腑鏃剁殑鍥炬爣鍚嶏紝鍙兘涓簎View鐨勫唴缃浘鏍囷紙榛樿star锛�
+ * @property {String} gutter 鏄熸槦涔嬮棿鐨勮窛绂伙紙榛樿10锛�
+ * @property {String Number} min-count 鏈�灏戦�変腑鏄熸槦鐨勪釜鏁帮紙榛樿0锛�
+ * @property {Boolean} allow-half 鏄惁鍏佽鍗婃槦閫夋嫨锛堥粯璁alse锛�
+ * @event {Function} change 閫変腑鐨勬槦鏄熷彂鐢熷彉鍖栨椂瑙﹀彂
+ * @example <u-rate :count="count" :current="2"></u-rate>
+ */
+
+export default {
+	name: 'u-rate',
+	props: {
+		// 鐢ㄤ簬v-model鍙屽悜缁戝畾閫変腑鐨勬槦鏄熸暟閲�
+		// 1.4.5鐗堟柊澧�
+		value: {
+			type: [Number, String],
+			default: -1
+		},
+		// 瑕佹樉绀虹殑鏄熸槦鏁伴噺
+		count: {
+			type: [Number, String],
+			default: 5
+		},
+		// 褰撳墠闇�瑕侀粯璁ら�変腑鐨勬槦鏄�(閫変腑鐨勪釜鏁�)
+		// 1.4.5鍚庨�氳繃value鍙屽悜缁戝畾锛屼笉鍐嶅缓璁娇鐢ㄦ鍙傛暟
+		current: {
+			type: [Number, String],
+			default: 0
+		},
+		// 鏄惁涓嶅彲閫変腑
+		disabled: {
+			type: Boolean,
+			default: false
+		},
+		// 鏄熸槦鐨勫ぇ灏忥紝鍗曚綅rpx
+		size: {
+			type: [Number, String],
+			default: 32
+		},
+		// 鏈�変腑鏃剁殑棰滆壊
+		inactiveColor: {
+			type: String,
+			default: '#b2b2b2'
+		},
+		// 閫変腑鐨勯鑹�
+		activeColor: {
+			type: String,
+			default: '#FA3534'
+		},
+		// 鏄熸槦涔嬮棿鐨勯棿璺濓紝鍗曚綅rpx
+		gutter: {
+			type: [Number, String],
+			default: 10
+		},
+		// 鏈�灏戣兘閫夋嫨鐨勬槦鏄熶釜鏁�
+		minCount: {
+			type: [Number, String],
+			default: 0
+		},
+		// 鏄惁鍏佽鍗婃槦(鍔熻兘灏氭湭瀹炵幇)
+		allowHalf: {
+			type: Boolean,
+			default: false
+		},
+		// 閫変腑鏃剁殑鍥炬爣(鏄熸槦)
+		activeIcon: {
+			type: String,
+			default: 'star-fill'
+		},
+		// 鏈�変腑鏃剁殑鍥炬爣(鏄熸槦)
+		inactiveIcon: {
+			type: String,
+			default: 'star'
+		},
+		// 鑷畾涔夋墿灞曞墠缂�锛屾柟渚跨敤鎴锋墿灞曡嚜宸辩殑鍥炬爣搴�
+		customPrefix: {
+			type: String,
+			default: 'uicon'
+		},
+		colors: {
+			type: Array,
+			default() {
+				return []
+			}
+		},
+		icons: {
+			type: Array,
+			default() {
+				return []
+			}
+		}
+	},
+	data() {
+		return {
+			// 鐢熸垚涓�涓敮涓�id锛屽惁鍒欎竴涓〉闈㈠涓瘎鍒嗙粍浠讹紝浼氶�犳垚鍐茬獊
+			elId: this.$u.guid(),
+			elClass: this.$u.guid(),
+			starBoxLeft: 0, // 璇勫垎鐩掑瓙宸﹁竟鍒板睆骞曞乏杈圭殑璺濈锛岀敤浜庢粦鍔ㄩ�夋嫨鏃惰绠楄窛绂�
+			// 褰撳墠婵�娲荤殑鏄熸槦鐨刬ndex锛屽鏋滃瓨鍦╲alue锛屼紭鍏堜娇鐢╲alue锛屽洜涓哄畠鍙互鍙屽悜缁戝畾(1.4.5鏂板)
+			activeIndex: this.value != -1 ? this.value : this.current,
+			starWidth: 0, // 姣忎釜鏄熸槦鐨勫搴�
+			starWidthArr: [] //姣忎釜鏄熸槦鏈�鍙宠竟鍒扮粍浠剁洅瀛愭渶宸﹁竟鐨勮窛绂�
+		}
+	},
+	watch: {
+		current(val) {
+			this.activeIndex = val
+		},
+		value(val) {
+			this.activeIndex = val
+		}
+	},
+	computed: {
+		decimal() {
+			if (this.disabled) {
+				return this.activeIndex * 100 % 100
+			} else if (this.allowHalf) {
+				return 50
+			}
+		},
+		elActiveIcon() {
+			const len = this.icons.length
+			// 姝ゅ瑙勫垯绫讳技浜庝笅鏂圭殑elActiveColor鍙傛暟锛岄兘鏄牴鎹竴瀹氱殑瑙勫垯锛屾樉绀轰笉鍚岀殑鍥炬爣
+			// 缁撴灉鍙兘濡傛锛歩cons鍙傛暟浼犻�掍簡3涓浘鏍囷紝褰撻�変腑涓や釜鏃讹紝鐢ㄧ涓�涓浘鏍囷紝4涓椂锛岀敤绗簩涓浘鏍�
+			// 绗笁涓椂锛岀敤绗笁涓浘鏍囦綔涓烘縺娲荤殑鍥炬爣
+			if (len && len <= this.count) {
+				const step = Math.round(this.activeIndex / Math.round(this.count / len))
+				if (step < 1) return this.icons[0]
+				if (step > len) return this.icons[len - 1]
+				return this.icons[step - 1]
+			}
+			return this.activeIcon
+		},
+		elActiveColor() {
+			const len = this.colors.length
+			// 濡傛灉鏈夎缃甤olors鍙傛暟(姝ゅ弬鏁扮敤浜庡皢鍥炬爣鍒嗘锛屾瘮濡備竴鍏�5棰楁槦锛宑olors浼�3涓鑹插�硷紝閭d箞鏍规嵁涓�瀹氱殑瑙勫垯锛�2棰楁槦鍙兘涓虹涓�涓鑹�
+			// 4棰楁槦涓虹浜屼釜棰滆壊鍊硷紝5棰楁槦涓虹涓変釜棰滆壊鍊�)
+			if (len && len <= this.count) {
+				const step = Math.round(this.activeIndex / Math.round(this.count / len))
+				if (step < 1) return this.colors[0]
+				if (step > len) return this.colors[len - 1]
+				return this.colors[step - 1]
+			}
+			return this.activeColor
+		}
+	},
+	methods: {
+		// 鑾峰彇璇勫垎缁勪欢鐩掑瓙鐨勫竷灞�淇℃伅
+		getElRectById() {
+			// uView灏佽鐨勮幏鍙栬妭鐐圭殑鏂规硶锛岃瑙佹枃妗�
+			this.$uGetRect('#' + this.elId).then(res => {
+				this.starBoxLeft = res.left
+			})
+		},
+		// 鑾峰彇鍗曚釜鏄熸槦鐨勫昂瀵�
+		getElRectByClass() {
+			// uView灏佽鐨勮幏鍙栬妭鐐圭殑鏂规硶锛岃瑙佹枃妗�
+			this.$uGetRect('.' + this.elClass).then(res => {
+				this.starWidth = res.width
+				// 鎶婃瘡涓槦鏄熷彸杈瑰埌缁勪欢鐩掑瓙宸﹁竟鐨勮窛绂绘斁鍏ユ暟缁勪腑
+				for (let i = 0; i < this.count; i++) {
+					this.starWidthArr[i] = (i + 1) * this.starWidth
+				}
+			})
+		},
+		// 鎵嬫寚婊戝姩
+		touchMove(e) {
+			if (this.disabled) {
+				return
+			}
+			if (!e.changedTouches[0]) {
+				return
+			}
+			const movePageX = e.changedTouches[0].pageX
+			// 婊戝姩鐐圭浉瀵逛簬璇勫垎鐩掑瓙宸﹁竟鐨勮窛绂�
+			const distance = movePageX - this.starBoxLeft
+
+			// 濡傛灉婊戝姩鍒颁簡璇勫垎鐩掑瓙鐨勫乏杈圭晫锛屽氨璁剧疆涓�0鏄�
+			if (distance <= 0) {
+				this.activeIndex = 0
+			}
+			// 婊戝姩鐨勮窛绂伙紝鐩稿綋浜庡灏戦鏄熸槦
+			let index = Math.ceil(distance / this.starWidth)
+			this.activeIndex = index > this.count ? this.count : index
+			// 瀵规渶灏戦鏄熸槦鐨勯檺鍒�
+			if (this.activeIndex < this.minCount) this.activeIndex = this.minCount
+			this.emitEvent()
+		},
+		// 閫氳繃鐐瑰嚮锛岀洿鎺ラ�変腑
+		click(index, e) {
+			if (this.disabled) {
+				return
+			}
+			// 鍗婃槦閫夋嫨锛屽皻鏈疄鐜�
+			if (this.allowHalf) {
+			}
+			// 瀵圭涓�涓槦鏄熺壒娈婂鐞嗭紝鍙湁涓�涓殑鏃跺�欙紝鐐瑰嚮鍙互鍙栨秷锛屽惁鍒欐棤娉曚綔0鏄熻瘎浠�
+			if (index == 1) {
+				if (this.activeIndex == 1) {
+					this.activeIndex = 0
+				} else {
+					this.activeIndex = 1
+				}
+			} else {
+				this.activeIndex = index
+			}
+			// 瀵规渶灏戦鏄熸槦鐨勯檺鍒�
+			if (this.activeIndex < this.minCount) this.activeIndex = this.minCount
+			this.emitEvent()
+		},
+		// 鍙戝嚭浜嬩欢
+		emitEvent() {
+			// 鍙戝嚭change浜嬩欢
+			this.$emit('change', this.activeIndex)
+			// 鍚屾椂淇敼鍙屽悜缁戝畾鐨剉alue鐨勫��
+			if (this.value != -1) {
+				this.$emit('input', this.activeIndex)
+			}
+		},
+		showDecimalIcon(index) {
+			return this.disabled && parseInt(this.activeIndex) === index
+		}
+	},
+	mounted() {
+		this.getElRectById()
+		this.getElRectByClass()
+	}
+}
+</script>
+
+<style scoped lang="scss">
+@import "../../libs/css/style.components.scss";
+
+.u-rate {
+	display: -webkit-inline-flex;
+	display: inline-flex;
+	align-items: center;
+	margin: 0;
+	padding: 0;
+}
+
+.u-icon {
+	box-sizing: border-box;
+}
+</style>

--
Gitblit v1.9.3