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-subsection/u-subsection.vue | 355 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 355 insertions(+), 0 deletions(-) diff --git a/uview-ui/components/u-subsection/u-subsection.vue b/uview-ui/components/u-subsection/u-subsection.vue new file mode 100644 index 0000000..b8fbd79 --- /dev/null +++ b/uview-ui/components/u-subsection/u-subsection.vue @@ -0,0 +1,355 @@ +<template> + <view class="u-subsection" :style="[subsectionStyle]"> + <view class="u-item u-line-1" :style="[itemStyle(index)]" @tap="click(index)" :class="[noBorderRight(index), 'u-item-' + index]" + v-for="(item, index) in listInfo" :key="index"> + <view :style="[textStyle(index)]" class="u-item-text u-line-1">{{ item.name }}</view> + </view> + <view class="u-item-bg" :style="[itemBarStyle]"></view> + </view> +</template> + +<script> + /** + * subsection 鍒嗘鍣� + * @description 璇ュ垎娈靛櫒涓�鑸敤浜庣敤鎴蜂粠鍑犱釜閫夐」涓�夋嫨鏌愪竴涓殑鍦烘櫙 + * @tutorial https://www.uviewui.com/components/subsection.html + * @property {Array} list 閫夐」鐨勬暟缁勶紝褰㈠紡瑙佷笂鏂�"鍩烘湰浣跨敤" + * @property {String Number} current 鍒濆鍖栨椂榛樿閫変腑鐨勯�夐」绱㈠紩鍊硷紙榛樿0锛� + * @property {String} active-color 婵�娲绘椂鐨勯鑹诧紝mode涓簊ubsection鏃跺浐瀹氫负鐧借壊锛堥粯璁�#303133锛� + * @property {String} inactive-color 鏈縺娲绘椂瀛椾綋鐨勯鑹诧紝mode涓簊ubsection鏃舵棤鏁堬紙榛樿#606266锛� + * @property {String} mode 妯″紡閫夋嫨锛岃瀹樼綉"妯″紡閫夋嫨"璇存槑锛堥粯璁utton锛� + * @property {String Number} font-size 瀛椾綋澶у皬锛屽崟浣峳px锛堥粯璁�28锛� + * @property {String Number} height 缁勪欢楂樺害锛屽崟浣峳px锛堥粯璁�70锛� + * @property {Boolean} animation 鏄惁寮�鍚姩鐢绘晥鏋滐紝瑙佷笂鏂硅鏄庯紙榛樿true锛� + * @property {Boolean} bold 婵�娲婚�夐」鐨勫瓧浣撴槸鍚﹀姞绮楋紙榛樿true锛� + * @property {String} bg-color 缁勪欢鑳屾櫙棰滆壊锛宮ode涓篵utton鏃舵湁鏁堬紙榛樿#eeeeef锛� + * @property {String} button-color 鎸夐挳鑳屾櫙棰滆壊锛宮ode涓篵utton鏃舵湁鏁堬紙榛樿#ffffff锛� + * @event {Function} change 鍒嗘鍣ㄩ�夐」鍙戠敓鏀瑰彉鏃惰Е鍙� + * @example <u-subsection active-color="#ff9900"></u-subsection> + */ + export default { + name: "u-subsection", + props: { + // tab鐨勬暟鎹� + list: { + type: Array, + default () { + return []; + } + }, + // 褰撳墠娲诲姩鐨則ab鐨刬ndex + current: { + type: [Number, String], + default: 0 + }, + // 婵�娲荤殑棰滆壊 + activeColor: { + type: String, + default: '#303133' + }, + // 鏈縺娲荤殑棰滆壊 + inactiveColor: { + type: String, + default: '#606266' + }, + // 妯″紡閫夋嫨锛宮ode=button涓烘寜閽舰寮忥紝mode=subsection鏃朵负鍒嗘妯″紡 + mode: { + type: String, + default: 'button' + }, + // 瀛椾綋澶у皬锛屽崟浣峳px + fontSize: { + type: [Number, String], + default: 28 + }, + // 鏄惁寮�鍚姩鐢绘晥鏋� + animation: { + type: Boolean, + default: true + }, + // 缁勪欢鐨勯珮搴︼紝鍗曚綅rpx + height: { + type: [Number, String], + default: 70 + }, + // 婵�娲籺ab鐨勫瓧浣撴槸鍚﹀姞绮� + bold: { + type: Boolean, + default: true + }, + // mode=button鏃讹紝缁勪欢鑳屾櫙棰滆壊 + bgColor: { + type: String, + default: '#eeeeef' + }, + // mode = button鏃讹紝婊戝潡鑳屾櫙棰滆壊 + buttonColor: { + type: String, + default: '#ffffff' + }, + // 鍦ㄥ垏鎹㈠垎娈靛櫒鐨勬椂鍊欙紝鏄惁璁╄澶囬渿涓�涓� + vibrateShort: { + type: Boolean, + default: false + } + }, + data() { + return { + listInfo: [], + itemBgStyle: { + width: 0, + left: 0, + backgroundColor: '#ffffff', + height: '100%', + transition: '' + }, + currentIndex: this.current, + buttonPadding: 3, // mode = button 鏃讹紝缁勪欢鐨勫唴杈硅窛 + borderRadius: 5, // 鍦嗚鍊� + firstTimeVibrateShort: true // 缁勪欢鍒濆鍖栨椂锛屼細瑙﹀彂current鍙樺寲锛屾鏃朵笉搴旈渿鍔� + }; + }, + watch: { + current: { + immediate: true, + handler(nVal) { + this.currentIndex = nVal; + this.changeSectionStatus(nVal); + } + } + }, + created() { + // 灏唋ist鐨勬暟鎹紝浼犲叆listInfo鏁扮粍锛屽洜涓轰笉鑳戒慨鏀筽rops浼犻�掔殑list鍊� + // 鍙互鎺ュ彈鐩存帴鏁扮粍褰㈠紡锛屾垨鑰呮暟缁勫厓绱犱负瀵硅薄鐨勫舰寮忥紝濡傦細['绠�浠�', '璇勮'],鎴栬�匸{name: '绠�浠�'}, {name: '璇勮'}] + this.listInfo = this.list.map((val, index) => { + if (typeof val != 'object') { + let obj = { + width: 0, + name: val + }; + return obj; + } else { + val.width = 0; + return val; + } + }); + }, + computed: { + // 璁剧疆mode=subsection鏃讹紝婊戝潡鐗规湁鐨勬牱寮� + noBorderRight() { + return index => { + if (this.mode != 'subsection') return; + let classs = ''; + // 涓嶆樉绀哄彸杈圭殑杈规 + if (index < this.list.length - 1) classs += ' u-none-border-right'; + // 鏄剧ず鏁翠釜缁勪欢鐨勫乏鍙宠竟鍦嗚 + if (index == 0) classs += ' u-item-first'; + if (index == this.list.length - 1) classs += ' u-item-last'; + return classs; + }; + }, + // 鏂囧瓧鐨勬牱寮� + textStyle() { + return index => { + let style = {}; + // 璁剧疆瀛椾綋棰滆壊 + if (this.mode == 'subsection') { + if (index == this.currentIndex) { + style.color = '#ffffff'; + } else { + style.color = this.activeColor; + } + } else { + if (index == this.currentIndex) { + style.color = this.activeColor; + } else { + style.color = this.inactiveColor; + } + } + // 瀛椾綋鍔犵矖 + if (index == this.currentIndex && this.bold) style.fontWeight = 'bold'; + // 鏂囧瓧澶у皬 + style.fontSize = this.fontSize + 'rpx'; + return style; + }; + }, + // 姣忎釜鍒嗘鍣╥tem鐨勬牱寮� + itemStyle() { + return index => { + let style = {}; + if (this.mode == 'subsection') { + // 璁剧疆border鐨勬牱寮� + style.borderColor = this.activeColor; + style.borderWidth = '1px'; + style.borderStyle = 'solid'; + } + return style; + }; + }, + // mode=button鏃讹紝澶栧眰view鐨勬牱寮� + subsectionStyle() { + let style = {}; + style.height = uni.upx2px(this.height) + 'px'; + if (this.mode == 'button') { + style.backgroundColor = this.bgColor; + style.padding = `${this.buttonPadding}px`; + style.borderRadius = `${this.borderRadius}px`; + } + return style; + }, + // 婊戝潡鐨勬牱寮� + itemBarStyle() { + let style = {}; + style.backgroundColor = this.activeColor; + style.zIndex = 1; + if (this.mode == 'button') { + style.backgroundColor = this.buttonColor; + style.borderRadius = `${this.borderRadius}px`; + style.bottom = `${this.buttonPadding}px`; + style.height = uni.upx2px(this.height) - this.buttonPadding * 2 + 'px'; + style.zIndex = 0; + } + return Object.assign(this.itemBgStyle, style); + } + }, + mounted() { + setTimeout(() => { + this.getTabsInfo(); + }, 10); + }, + methods: { + // 鏀瑰彉婊戝潡鐨勬牱寮� + changeSectionStatus(nVal) { + if (this.mode == 'subsection') { + // 鏍规嵁婊戝潡鍦ㄦ渶宸﹁竟鍜屾渶鍙宠竟鏃讹紝鏄剧ず宸﹁竟鍜屽彸杈圭殑鍦嗚 + if (nVal == this.list.length - 1) { + this.itemBgStyle.borderRadius = `0 ${this.buttonPadding}px ${this.buttonPadding}px 0`; + } + if (nVal == 0) { + this.itemBgStyle.borderRadius = `${this.buttonPadding}px 0 0 ${this.buttonPadding}px`; + } + if (nVal > 0 && nVal < this.list.length - 1) { + this.itemBgStyle.borderRadius = '0'; + } + } + // 鏇存柊婊戝潡鐨勪綅缃� + setTimeout(() => { + this.itemBgLeft(); + }, 10); + if (this.vibrateShort && !this.firstTimeVibrateShort) { + // 浣挎墜鏈轰骇鐢熺煭淇冮渿鍔紝寰俊灏忕▼搴忔湁鏁堬紝APP(HX 2.6.8)鍜孒5鏃犳晥 + // #ifndef H5 + uni.vibrateShort(); + // #endif + } + // 绗竴娆¤繃鍚庯紝璁剧疆firstTimeVibrateShort涓篺alse锛岃鍏朵笅涓�娆″彲浠ラ渿鍔�(濡傛灉鍏佽闇囧姩鐨勮瘽) + this.firstTimeVibrateShort = false; + }, + click(index) { + // 涓嶅厑璁哥偣鍑诲綋鍓嶆縺娲婚�夐」 + if (index == this.currentIndex) return; + this.currentIndex = index; + this.changeSectionStatus(index); + this.$emit('change', Number(index)); + }, + // 鑾峰彇鍚勪釜tab鐨勮妭鐐逛俊鎭� + getTabsInfo() { + let view = uni.createSelectorQuery().in(this); + for (let i = 0; i < this.list.length; i++) { + view.select('.u-item-' + i).boundingClientRect(); + } + view.exec(res => { + if (!res.length) { + setTimeout(() => { + this.getTabsInfo(); + return; + }, 10); + } + // 灏嗗垎娈靛櫒姣忎釜item鐨勫搴︼紝鏀惧叆listInfo鏁扮粍 + res.map((val, index) => { + this.listInfo[index].width = val.width; + }); + // 鍒濆鍖栨粦鍧楃殑瀹藉害 + if (this.mode == 'subsection') { + this.itemBgStyle.width = this.listInfo[0].width + 'px'; + } else if (this.mode == 'button') { + this.itemBgStyle.width = this.listInfo[0].width + 'px'; + } + // 鍒濆鍖栨粦鍧楃殑浣嶇疆 + this.itemBgLeft(); + }); + }, + itemBgLeft() { + // 鏍规嵁鏄惁寮�鍚姩鐢绘晥鏋滐紝 + if (this.animation) { + this.itemBgStyle.transition = 'all 0.35s'; + } else { + this.itemBgStyle.transition = 'all 0s'; + } + let left = 0; + // 璁$畻褰撳墠娲昏穬item鍒扮粍浠跺乏杈圭殑璺濈 + this.listInfo.map((val, index) => { + if (index < this.currentIndex) left += val.width; + }); + // 鏍规嵁mode涓嶅悓妯″紡锛岃绠楁粦鍧楅渶瑕佺Щ鍔ㄧ殑璺濈 + if (this.mode == 'subsection') { + this.itemBgStyle.left = left + 'px'; + } else if (this.mode == 'button') { + this.itemBgStyle.left = left + this.buttonPadding + 'px'; + } + } + } + }; +</script> + +<style lang="scss" scoped> + @import "../../libs/css/style.components.scss"; + + .u-subsection { + @include vue-flex; + align-items: center; + overflow: hidden; + position: relative; + } + + .u-item { + flex: 1; + text-align: center; + font-size: 26rpx; + height: 100%; + @include vue-flex; + align-items: center; + justify-content: center; + color: $u-main-color; + padding: 0 6rpx; + } + + .u-item-bg { + background-color: $u-type-primary; + position: absolute; + z-index: -1; + } + + .u-none-border-right { + border-right: none !important; + } + + .u-item-first { + border-top-left-radius: 8rpx; + border-bottom-left-radius: 8rpx; + } + + .u-item-last { + border-top-right-radius: 8rpx; + border-bottom-right-radius: 8rpx; + } + + .u-item-text { + transition: all 0.35s; + color: $u-main-color; + @include vue-flex; + align-items: center; + position: relative; + z-index: 3; + } +</style> -- Gitblit v1.9.3