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-rate/u-rate.vue | 304 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 304 insertions(+), 0 deletions(-) diff --git a/uni_modules/uview-ui/components/u-rate/u-rate.vue b/uni_modules/uview-ui/components/u-rate/u-rate.vue new file mode 100644 index 0000000..5992038 --- /dev/null +++ b/uni_modules/uview-ui/components/u-rate/u-rate.vue @@ -0,0 +1,304 @@ +<template> + <view + class="u-rate" + :id="elId" + ref="u-rate" + :style="[$u.addStyle(customStyle)]" + > + <view + class="u-rate__content" + @touchmove.stop="touchMove" + @touchend.stop="touchEnd" + > + <view + class="u-rate__content__item" + v-for="(item, index) in Number(count)" + :key="index" + :class="[elClass]" + > + <view + class="u-rate__content__item__icon-wrap" + ref="u-rate__content__item__icon-wrap" + @tap.stop="clickHandler($event, index + 1)" + > + <u-icon + :name=" + Math.floor(activeIndex) > index + ? activeIcon + : inactiveIcon + " + :color=" + disabled + ? '#c8c9cc' + : Math.floor(activeIndex) > index + ? activeColor + : inactiveColor + " + :custom-style="{ + padding: `0 ${$u.addUnit(gutter / 2)}`, + }" + :size="size" + ></u-icon> + </view> + <view + v-if="allowHalf" + @tap.stop="clickHandler($event, index + 1)" + class="u-rate__content__item__icon-wrap u-rate__content__item__icon-wrap--half" + :style="[{ + width: $u.addUnit(rateWidth / 2), + }]" + ref="u-rate__content__item__icon-wrap" + > + <u-icon + :name=" + Math.ceil(activeIndex) > index + ? activeIcon + : inactiveIcon + " + :color=" + disabled + ? '#c8c9cc' + : Math.ceil(activeIndex) > index + ? activeColor + : inactiveColor + " + :custom-style="{ + padding: `0 ${$u.addUnit(gutter / 2)}` + }" + :size="size" + ></u-icon> + </view> + </view> + </view> + </view> +</template> + +<script> + import props from './props.js'; + + // #ifdef APP-NVUE + const dom = weex.requireModule("dom"); + // #endif + /** + * rate 璇勫垎 + * @description 璇ョ粍浠朵竴鑸敤浜庢弧鎰忓害璋冩煡锛屾槦鍨嬭瘎鍒嗙殑鍦烘櫙 + * @tutorial https://www.uviewui.com/components/rate.html + * @property {String | Number} value 鐢ㄤ簬v-model鍙屽悜缁戝畾閫変腑鐨勬槦鏄熸暟閲� (榛樿 1 ) + * @property {String | Number} count 鏈�澶氬彲閫夌殑鏄熸槦鏁伴噺 锛堥粯璁� 5 锛� + * @property {Boolean} disabled 鏄惁绂佹鐢ㄦ埛鎿嶄綔 锛堥粯璁� false 锛� + * @property {Boolean} readonly 鏄惁鍙 锛堥粯璁� false 锛� + * @property {String | Number} size 鏄熸槦鐨勫ぇ灏忥紝鍗曚綅px 锛堥粯璁� 18 锛� + * @property {String} inactiveColor 鏈�変腑鏄熸槦鐨勯鑹� 锛堥粯璁� '#b2b2b2' 锛� + * @property {String} activeColor 閫変腑鐨勬槦鏄熼鑹� 锛堥粯璁� '#FA3534' 锛� + * @property {String | Number} gutter 鏄熸槦涔嬮棿鐨勮窛绂� 锛堥粯璁� 4 锛� + * @property {String | Number} minCount 鏈�灏戦�変腑鏄熸槦鐨勪釜鏁� 锛堥粯璁� 1 锛� + * @property {Boolean} allowHalf 鏄惁鍏佽鍗婃槦閫夋嫨 锛堥粯璁� false 锛� + * @property {String} activeIcon 閫変腑鏃剁殑鍥炬爣鍚嶏紝鍙兘涓簎View鐨勫唴缃浘鏍� 锛堥粯璁� 'star-fill' 锛� + * @property {String} inactiveIcon 鏈�変腑鏃剁殑鍥炬爣鍚嶏紝鍙兘涓簎View鐨勫唴缃浘鏍� 锛堥粯璁� 'star' 锛� + * @property {Boolean} touchable 鏄惁鍙互閫氳繃婊戝姩鎵嬪娍閫夋嫨璇勫垎 锛堥粯璁� 'true' 锛� + * @property {Object} customStyle 缁勪欢鐨勬牱寮忥紝瀵硅薄褰㈠紡 + * @event {Function} change 閫変腑鐨勬槦鏄熷彂鐢熷彉鍖栨椂瑙﹀彂 + * @example <u-rate :count="count" :value="2"></u-rate> + */ + export default { + name: "u-rate", + mixins: [uni.$u.mpMixin, uni.$u.mixin,props], + data() { + return { + // 鐢熸垚涓�涓敮涓�id锛屽惁鍒欎竴涓〉闈㈠涓瘎鍒嗙粍浠讹紝浼氶�犳垚鍐茬獊 + elId: uni.$u.guid(), + elClass: uni.$u.guid(), + rateBoxLeft: 0, // 璇勫垎鐩掑瓙宸﹁竟鍒板睆骞曞乏杈圭殑璺濈锛岀敤浜庢粦鍔ㄩ�夋嫨鏃惰绠楄窛绂� + activeIndex: this.value, + rateWidth: 0, // 姣忎釜鏄熸槦鐨勫搴� + // 鏍囪瘑鏄惁姝e湪婊戝姩锛岀敱浜巌OS浜嬩欢涓妕ouch姣攃lick鍏堣Е鍙戯紝瀵艰嚧蹇�熸粦鍔ㄧ粨鏉熷悗锛屾帴鐫�瑙﹀彂click锛屽鑷翠簨浠舵贩涔辫�屽嚭閿� + moving: false, + }; + }, + watch: { + value(val) { + this.activeIndex = val; + }, + activeIndex: 'emitEvent' + }, + methods: { + init() { + uni.$u.sleep().then(() => { + this.getRateItemRect(); + this.getRateIconWrapRect(); + }) + }, + // 鑾峰彇璇勫垎缁勪欢鐩掑瓙鐨勫竷灞�淇℃伅 + async getRateItemRect() { + await uni.$u.sleep(); + // uView灏佽鐨勮幏鍙栬妭鐐圭殑鏂规硶锛岃瑙佹枃妗� + // #ifndef APP-NVUE + this.$uGetRect("#" + this.elId).then((res) => { + this.rateBoxLeft = res.left; + }); + // #endif + // #ifdef APP-NVUE + dom.getComponentRect(this.$refs["u-rate"], (res) => { + this.rateBoxLeft = res.size.left; + }); + // #endif + }, + // 鑾峰彇鍗曚釜鏄熸槦鐨勫昂瀵� + getRateIconWrapRect() { + // uView灏佽鐨勮幏鍙栬妭鐐圭殑鏂规硶锛岃瑙佹枃妗� + // #ifndef APP-NVUE + this.$uGetRect("." + this.elClass).then((res) => { + this.rateWidth = res.width; + }); + // #endif + // #ifdef APP-NVUE + dom.getComponentRect( + this.$refs["u-rate__content__item__icon-wrap"][0], + (res) => { + this.rateWidth = res.size.width; + } + ); + // #endif + }, + // 鎵嬫寚婊戝姩 + touchMove(e) { + // 濡傛灉绂佹閫氳繃鎵嬪姩婊戝姩閫夋嫨锛岃繑鍥� + if (!this.touchable) { + return; + } + this.preventEvent(e); + const x = e.changedTouches[0].pageX; + this.getActiveIndex(x); + }, + // 鍋滄婊戝姩 + touchEnd(e) { + // 濡傛灉绂佹閫氳繃鎵嬪姩婊戝姩閫夋嫨锛岃繑鍥� + if (!this.touchable) { + return; + } + this.preventEvent(e); + const x = e.changedTouches[0].pageX; + this.getActiveIndex(x); + }, + // 閫氳繃鐐瑰嚮锛岀洿鎺ラ�変腑 + clickHandler(e, index) { + // ios涓婏紝moving鐘舵�佸彇娑堜簨浠惰Е鍙� + if (uni.$u.os() === "ios" && this.moving) { + return; + } + this.preventEvent(e); + let x = 0; + // 鐐瑰嚮鏃讹紝鍦╪vue涓婏紝鏃犳硶鑾峰緱鐐瑰嚮鐨勫潗鏍囷紝鎵�浠ユ棤娉曞疄鐜扮偣鍑诲崐鏄熼�夋嫨 + // #ifndef APP-NVUE + x = e.changedTouches[0].pageX; + // #endif + // #ifdef APP-NVUE + // nvue涓嬶紝鏃犳硶閫氳繃鐐瑰嚮鑾峰緱鍧愭爣淇℃伅锛岃繖閲岄�氳繃鍏冪礌鐨勪綅缃昂瀵稿�兼ā鎷熷潗鏍� + x = index * this.rateWidth + this.rateBoxLeft; + // #endif + this.getActiveIndex(x,true); + }, + // 鍙戝嚭浜嬩欢 + emitEvent() { + // 鍙戝嚭change浜嬩欢 + this.$emit("change", this.activeIndex); + // 鍚屾椂淇敼鍙屽悜缁戝畾鐨剉alue鐨勫�� + this.$emit("input", this.activeIndex); + }, + // 鑾峰彇褰撳墠婵�娲荤殑璇勫垎鍥炬爣 + getActiveIndex(x,isClick = false) { + if (this.disabled || this.readonly) { + return; + } + // 鍒ゆ柇褰撳墠鎿嶄綔鐨勭偣鐨剎鍧愭爣鍊硷紝鏄惁鍦ㄥ厑璁哥殑杈圭晫鑼冨洿鍐� + const allRateWidth = this.rateWidth * this.count + this.rateBoxLeft; + // 濡傛灉灏忎簬绗竴涓浘鏍囩殑宸﹁竟鐣岋紝璁剧疆涓烘渶灏忓�硷紝濡傛灉澶т簬鎵�鏈夊浘鏍囩殑瀹藉害锛屽垯璁剧疆涓烘渶澶у�� + x = uni.$u.range(this.rateBoxLeft, allRateWidth, x) - this.rateBoxLeft + // 婊戝姩鐐圭浉瀵逛簬璇勫垎鐩掑瓙宸﹁竟鐨勮窛绂� + const distance = x; + // 婊戝姩鐨勮窛绂伙紝鐩稿綋浜庡灏戦鏄熸槦 + let index; + // 鍒ゆ柇鏄惁鍏佽鍗婃槦 + if (this.allowHalf) { + index = Math.floor(distance / this.rateWidth); + // 鍙栦綑锛屽垽鏂皬鏁扮殑鍖洪棿鑼冨洿 + const decimal = distance % this.rateWidth; + if (decimal <= this.rateWidth / 2 && decimal > 0) { + index += 0.5; + } else if (decimal > this.rateWidth / 2) { + index++; + } + } else { + index = Math.floor(distance / this.rateWidth); + // 鍙栦綑锛屽垽鏂皬鏁扮殑鍖洪棿鑼冨洿 + const decimal = distance % this.rateWidth; + // 闈炲崐鏄熸椂锛屽彧鏈夎秴杩囦簡鍥炬爣鐨勪竴鍗婅窛绂伙紝鎵嶈涓烘槸閫夋嫨浜嗚繖棰楁槦 + if (isClick){ + if (decimal > 0) index++; + } else { + if (decimal > this.rateWidth / 2) index++; + } + + } + this.activeIndex = Math.min(index, this.count); + // 瀵规渶灏戦鏄熸槦鐨勯檺鍒� + if (this.activeIndex < this.minCount) { + this.activeIndex = this.minCount; + } + + // 璁剧疆寤舵椂涓轰簡璁ヽlick浜嬩欢鍦╰ouchmove涔嬪墠瑙﹀彂 + setTimeout(() => { + this.moving = true; + }, 10); + // 涓�瀹氭椂闂村悗锛屽彇娑堟爣璇嗕负绉诲姩涓姸鎬侊紝鏄负浜嗚click浜嬩欢鏃犳晥 + setTimeout(() => { + this.moving = false; + }, 10); + }, + }, + mounted() { + this.init(); + }, + }; +</script> + +<style lang="scss" scoped> +@import "../../libs/css/components.scss"; +$u-rate-margin: 0 !default; +$u-rate-padding: 0 !default; +$u-rate-item-icon-wrap-half-top: 0 !default; +$u-rate-item-icon-wrap-half-left: 0 !default; + +.u-rate { + @include flex; + align-items: center; + margin: $u-rate-margin; + padding: $u-rate-padding; + /* #ifndef APP-NVUE */ + touch-action: none; + /* #endif */ + + &__content { + @include flex; + + &__item { + position: relative; + + &__icon-wrap { + &--half { + position: absolute; + overflow: hidden; + top: $u-rate-item-icon-wrap-half-top; + left: $u-rate-item-icon-wrap-half-left; + } + } + } + } +} + +.u-icon { + /* #ifndef APP-NVUE */ + box-sizing: border-box; + /* #endif */ +} +</style> -- Gitblit v1.9.3