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

diff --git a/uni_modules/uview-ui/components/u-subsection/u-subsection.vue b/uni_modules/uview-ui/components/u-subsection/u-subsection.vue
new file mode 100644
index 0000000..cc4d540
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-subsection/u-subsection.vue
@@ -0,0 +1,299 @@
+<template>
+    <view
+        class="u-subsection"
+        ref="u-subsection"
+        :class="[`u-subsection--${mode}`]"
+        :style="[$u.addStyle(customStyle), wrapperStyle]"
+    >
+        <view
+            class="u-subsection__bar"
+            ref="u-subsection__bar"
+            :style="[barStyle]"
+            :class="[
+                mode === 'button' && 'u-subsection--button__bar',
+                current === 0 &&
+                    mode === 'subsection' &&
+                    'u-subsection__bar--first',
+                current > 0 &&
+                    current < list.length - 1 &&
+                    mode === 'subsection' &&
+                    'u-subsection__bar--center',
+                current === list.length - 1 &&
+                    mode === 'subsection' &&
+                    'u-subsection__bar--last',
+            ]"
+        ></view>
+        <view
+            class="u-subsection__item"
+            :class="[
+                `u-subsection__item--${index}`,
+                index < list.length - 1 &&
+                    'u-subsection__item--no-border-right',
+                index === 0 && 'u-subsection__item--first',
+                index === list.length - 1 && 'u-subsection__item--last',
+            ]"
+            :ref="`u-subsection__item--${index}`"
+            :style="[itemStyle(index)]"
+            @tap="clickHandler(index)"
+            v-for="(item, index) in list"
+            :key="index"
+        >
+            <text
+                class="u-subsection__item__text"
+                :style="[textStyle(index)]"
+                >{{ getText(item) }}</text
+            >
+        </view>
+    </view>
+</template>
+
+<script>
+// #ifdef APP-NVUE
+const dom = uni.requireNativePlugin("dom");
+const animation = uni.requireNativePlugin("animation");
+// #endif
+import props from "./props.js";
+/**
+ * Subsection 鍒嗘鍣�
+ * @description 璇ュ垎娈靛櫒涓�鑸敤浜庣敤鎴蜂粠鍑犱釜閫夐」涓�夋嫨鏌愪竴涓殑鍦烘櫙
+ * @tutorial https://www.uviewui.com/components/subsection.html
+ * @property {Array}			list			tab鐨勬暟鎹�
+ * @property {String 锝� Number}	current			褰撳墠娲诲姩鐨則ab鐨刬ndex锛堥粯璁� 0 锛�
+ * @property {String}			activeColor		婵�娲绘椂鐨勯鑹诧紙榛樿 '#3c9cff' 锛�
+ * @property {String}			inactiveColor	鏈縺娲绘椂鐨勯鑹诧紙榛樿 '#303133' 锛�
+ * @property {String}			mode			妯″紡閫夋嫨锛宮ode=button涓烘寜閽舰寮忥紝mode=subsection鏃朵负鍒嗘妯″紡锛堥粯璁� 'button' 锛�
+ * @property {String 锝� Number}	fontSize		瀛椾綋澶у皬锛屽崟浣峱x锛堥粯璁� 12 锛�
+ * @property {Boolean}			bold			婵�娲婚�夐」鐨勫瓧浣撴槸鍚﹀姞绮楋紙榛樿 true 锛�
+ * @property {String}			bgColor			缁勪欢鑳屾櫙棰滆壊锛宮ode涓篵utton鏃舵湁鏁堬紙榛樿 '#eeeeef' 锛�
+ * @property {Object}			customStyle		瀹氫箟闇�瑕佺敤鍒扮殑澶栭儴鏍峰紡
+ * @property {String}	        keyName	        浠巂list`鍏冪礌瀵硅薄涓鍙栫殑閿悕锛堥粯璁� 'name' 锛�
+ *
+ * @event {Function} change		鍒嗘鍣ㄩ�夐」鍙戠敓鏀瑰彉鏃惰Е鍙�  鍥炶皟 index锛氶�夐」鐨刬ndex绱㈠紩鍊硷紝浠�0寮�濮�
+ * @example <u-subsection :list="list" :current="curNow" @change="sectionChange"></u-subsection>
+ */
+export default {
+    name: "u-subsection",
+    mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+    data() {
+        return {
+            // 缁勪欢灏哄
+            itemRect: {
+                width: 0,
+                height: 0,
+            },
+        };
+    },
+    watch: {
+        list(newValue, oldValue) {
+            this.init();
+        },
+        current: {
+            immediate: true,
+            handler(n) {
+                // #ifdef APP-NVUE
+                // 鍦ㄥ畨鍗搉vue涓婏紝濡傛灉閫氳繃translateX杩涜浣嶇Щ锛屽埌鏈�鍚庝竴涓椂锛屼細瀵艰嚧鍙充晶鏃犳硶缁樺埗鍦嗚
+                // 鏁呯敤animation妯″潡杩涜浣嶇Щ
+                const ref = this.$refs?.["u-subsection__bar"]?.ref;
+                // 涓嶅瓨鍦╮ef鐨勬椂鍊�(鐞嗚В涓虹涓�娆″垵濮嬪寲鏃讹紝闇�瑕佹覆鏌揹om锛岃繘琛屼竴瀹氬欢鏃跺啀鑾峰彇ref)锛岃繖閲岀殑100ms鏄粡杩囨祴璇曞緱鍑虹殑缁撴灉(鏌愪簺瀹夊崜闇�瑕佸欢鏃朵箙涓�鐐�)锛屽嬁闅忔剰淇敼
+                uni.$u.sleep(ref ? 0 : 100).then(() => {
+                    animation.transition(this.$refs["u-subsection__bar"].ref, {
+                        styles: {
+                            transform: `translateX(${
+                                n * this.itemRect.width
+                            }px)`,
+                            transformOrigin: "center center",
+                        },
+                        duration: 300,
+                    });
+                });
+                // #endif
+            },
+        },
+    },
+    computed: {
+        wrapperStyle() {
+            const style = {};
+            // button妯″紡鏃讹紝璁剧疆鑳屾櫙鑹�
+            if (this.mode === "button") {
+                style.backgroundColor = this.bgColor;
+            }
+            return style;
+        },
+        // 婊戝潡鐨勬牱寮�
+        barStyle() {
+            const style = {};
+            style.width = `${this.itemRect.width}px`;
+            style.height = `${this.itemRect.height}px`;
+            // 閫氳繃translateX绉诲姩婊戝潡锛屽叾绉诲姩鐨勮窛绂讳负绱㈠紩*item鐨勫搴�
+            // #ifndef APP-NVUE
+            style.transform = `translateX(${
+                this.current * this.itemRect.width
+            }px)`;
+            // #endif
+            if (this.mode === "subsection") {
+                // 鍦╯ubsection妯″紡涓嬶紝闇�瑕佸姩鎬佽缃粦鍧楃殑鍦嗚锛屽洜涓虹Щ鍔ㄦ粦鍧椾娇鐢ㄧ殑鏄痶ranslateX锛屾棤娉曢�氳繃鐖跺厓绱犺缃畂verflow: hidden闅愯棌婊戝潡鐨勭洿瑙�
+                style.backgroundColor = this.activeColor;
+            }
+            return style;
+        },
+        // 鍒嗘鍣╥tem鐨勬牱寮�
+        itemStyle(index) {
+            return (index) => {
+                const style = {};
+                if (this.mode === "subsection") {
+                    // 璁剧疆border鐨勬牱寮�
+                    style.borderColor = this.activeColor;
+                    style.borderWidth = "1px";
+                    style.borderStyle = "solid";
+                }
+                return style;
+            };
+        },
+        // 鍒嗘鍣ㄦ枃瀛楅鑹�
+        textStyle(index) {
+            return (index) => {
+                const style = {};
+                style.fontWeight =
+                    this.bold && this.current === index ? "bold" : "normal";
+                style.fontSize = uni.$u.addUnit(this.fontSize);
+                // subsection妯″紡涓嬶紝婵�娲绘椂榛樿涓虹櫧鑹茬殑鏂囧瓧
+                if (this.mode === "subsection") {
+                    style.color =
+                        this.current === index ? "#fff" : this.inactiveColor;
+                } else {
+                    // button妯″紡涓嬶紝婵�娲绘椂鏂囧瓧棰滆壊榛樿涓篴ctiveColor
+                    style.color =
+                        this.current === index
+                            ? this.activeColor
+                            : this.inactiveColor;
+                }
+                return style;
+            };
+        },
+    },
+    mounted() {
+        this.init();
+    },
+    methods: {
+        init() {
+            uni.$u.sleep().then(() => this.getRect());
+        },
+		// 鍒ゆ柇灞曠ず鏂囨湰
+		getText(item) {
+			return typeof item === 'object' ? item[this.keyName] : item
+		},
+        // 鑾峰彇缁勪欢鐨勫昂瀵�
+        getRect() {
+            // #ifndef APP-NVUE
+            this.$uGetRect(".u-subsection__item--0").then((size) => {
+                this.itemRect = size;
+            });
+            // #endif
+
+            // #ifdef APP-NVUE
+            const ref = this.$refs["u-subsection__item--0"][0];
+            ref &&
+                dom.getComponentRect(ref, (res) => {
+                    this.itemRect = res.size;
+                });
+            // #endif
+        },
+        clickHandler(index) {
+            this.$emit("change", index);
+        },
+    },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "../../libs/css/components.scss";
+
+.u-subsection {
+    @include flex;
+    position: relative;
+    overflow: hidden;
+	/* #ifndef APP-NVUE */
+	width: 100%;
+	box-sizing: border-box;
+	/* #endif */
+
+    &--button {
+        height: 32px;
+        background-color: rgb(238, 238, 239);
+        padding: 3px;
+        border-radius: 3px;
+        align-items: stretch;
+
+        &__bar {
+            background-color: #ffffff;
+            border-radius: 3px !important;
+        }
+    }
+
+    &--subsection {
+        height: 30px;
+    }
+
+    &__bar {
+        position: absolute;
+        /* #ifndef APP-NVUE */
+        transition-property: transform, color;
+        transition-duration: 0.3s;
+        transition-timing-function: ease-in-out;
+        /* #endif */
+
+        &--first {
+            border-top-left-radius: 3px;
+            border-bottom-left-radius: 3px;
+            border-top-right-radius: 0px;
+            border-bottom-right-radius: 0px;
+        }
+
+        &--center {
+            border-top-left-radius: 0px;
+            border-bottom-left-radius: 0px;
+            border-top-right-radius: 0px;
+            border-bottom-right-radius: 0px;
+        }
+
+        &--last {
+            border-top-left-radius: 0px;
+            border-bottom-left-radius: 0px;
+            border-top-right-radius: 3px;
+            border-bottom-right-radius: 3px;
+        }
+    }
+
+    &__item {
+        @include flex;
+        flex: 1;
+        justify-content: center;
+        align-items: center;
+        // vue鐜涓嬶紝闇�瑕佽缃浉瀵瑰畾浣嶏紝鍥犱负婊戝潡涓虹粷瀵瑰畾浣嶏紝item闇�瑕佸湪婊戝潡鐨勪笂闈�
+        position: relative;
+
+        &--no-border-right {
+            border-right-width: 0 !important;
+        }
+
+        &--first {
+            border-top-left-radius: 3px;
+            border-bottom-left-radius: 3px;
+        }
+
+        &--last {
+            border-top-right-radius: 3px;
+            border-bottom-right-radius: 3px;
+        }
+
+        &__text {
+            font-size: 12px;
+            line-height: 12px;
+            @include flex;
+            align-items: center;
+            transition-property: color;
+            transition-duration: 0.3s;
+        }
+    }
+}
+</style>

--
Gitblit v1.9.3