From 1e61215b48e59e94c1ed98e4ef956227d689d6bc Mon Sep 17 00:00:00 2001
From: quanyawei <401863037@qq.com>
Date: Mon, 06 Nov 2023 08:48:39 +0800
Subject: [PATCH] fix:小程序订阅消息

---
 uni_modules/uview-ui/components/u-index-list/u-index-list.vue |  440 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 440 insertions(+), 0 deletions(-)

diff --git a/uni_modules/uview-ui/components/u-index-list/u-index-list.vue b/uni_modules/uview-ui/components/u-index-list/u-index-list.vue
new file mode 100644
index 0000000..d712618
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-index-list/u-index-list.vue
@@ -0,0 +1,440 @@
+<template>
+	<view class="u-index-list">
+		<!-- #ifdef APP-NVUE -->
+		<list
+			:scrollTop="scrollTop"
+			enable-back-to-top
+			:offset-accuracy="1"
+			:style="{
+				maxHeight: $u.addUnit(scrollViewHeight)
+			}"
+			@scroll="scrollHandler"
+			ref="uList"
+		>
+			<cell
+				v-if="$slots.header"
+				ref="header"
+			>
+				<slot name="header" />
+			</cell>
+			<slot />
+			<cell v-if="$slots.footer">
+				<slot name="footer" />
+			</cell>
+		</list>
+		<!-- #endif -->
+		<!-- #ifndef APP-NVUE -->
+		<scroll-view
+			:scrollTop="scrollTop"
+			:scrollIntoView="scrollIntoView"
+			:offset-accuracy="1"
+			:style="{
+				maxHeight: $u.addUnit(scrollViewHeight)
+			}"
+			scroll-y
+			@scroll="scrollHandler"
+			ref="uList"
+		>
+			<view v-if="$slots.header">
+				<slot name="header" />
+			</view>
+			<slot />
+			<view v-if="$slots.footer">
+				<slot name="footer" />
+			</view>
+		</scroll-view>
+		<!-- #endif -->
+		<view
+			class="u-index-list__letter"
+			ref="u-index-list__letter"
+			:style="{ top: $u.addUnit(letterInfo.top || 100) }"
+			@touchstart="touchStart"
+			@touchmove.stop.prevent="touchMove"
+			@touchend.stop.prevent="touchEnd"
+			@touchcancel.stop.prevent="touchEnd"
+		>
+			<view
+				class="u-index-list__letter__item"
+				v-for="(item, index) in uIndexList"
+				:key="index"
+				:style="{
+					backgroundColor: activeIndex === index ? activeColor : 'transparent'
+				}"
+			>
+				<text
+					class="u-index-list__letter__item__index"
+					:style="{color: activeIndex === index ? '#fff' : inactiveColor}"
+				>{{ item }}</text>
+			</view>
+		</view>
+		<u-transition
+			mode="fade"
+			:show="touching"
+			:customStyle="{
+				position: 'fixed',
+				right: '50px',
+				top: $u.addUnit(indicatorTop),
+				zIndex: 2
+			}"
+		>
+			<view
+				class="u-index-list__indicator"
+				:class="['u-index-list__indicator--show']"
+				:style="{
+					height: $u.addUnit(indicatorHeight),
+					width: $u.addUnit(indicatorHeight)
+				}"
+			>
+				<text class="u-index-list__indicator__text">{{ uIndexList[activeIndex] }}</text>
+			</view>
+		</u-transition>
+	</view>
+</template>
+
+<script>
+	const indexList = () => {
+		const indexList = [];
+		const charCodeOfA = 'A'.charCodeAt(0);
+		for (let i = 0; i < 26; i++) {
+			indexList.push(String.fromCharCode(charCodeOfA + i));
+		}
+		return indexList;
+	}
+	import props from './props.js';
+	// #ifdef APP-NVUE
+	// ������weex������������KPI���������������������������������������������������������������������������dom���������������������
+	const dom = uni.requireNativePlugin('dom')
+	// #endif
+	/**
+	 * IndexList ������������
+	 * @description  ������������������������������������
+	 * @tutorial https://uviewui.com/components/indexList.html
+	 * @property {String}			inactiveColor	������������������������������ ( ������ '#606266' )
+	 * @property {String}			activeColor		��������������������������� ( ������ '#5677fc' )
+	 * @property {Array}			indexList		���������������������������������
+	 * @property {Boolean}			sticky			������������������������������ ( ������ true )
+	 * @property {String | Number}	customNavHeight	��������������������������� ( ������ 0 )
+	 * */ 
+	export default {
+		name: 'u-index-list',
+		mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+		// #ifdef MP-WEIXIN
+		// ���������������������������������������������������Vue������������������������������������flex������
+		options: {
+			virtualHost: true
+		},
+		// #endif
+		data() {
+			return {
+				// ������������������������������������
+				activeIndex: -1,
+				touchmoveIndex: 1,
+				// ���������������������
+				letterInfo: {
+					height: 0,
+					itemHeight: 0,
+					top: 0
+				},
+				// ������������������������������������������������������������������������������������������������������������������������������������
+				indicatorHeight: 50,
+				// ������������������������top���������������������������������������������
+				// indicatorTop: 0
+				// ���������������������������������
+				touching: false,
+				// ���������������top���
+				scrollTop: 0,
+				// scroll-view���������
+				scrollViewHeight: 0,
+				// ������������
+				sys: uni.$u.sys(),
+				scrolling: false,
+				scrollIntoView: '',
+			}
+		},
+		computed: {
+			// ������������������������indexList������������������������������������������������A-Z������
+			uIndexList() {
+				return this.indexList.length ? this.indexList : indexList()
+			},
+			// ������������������������top���������������������������������������������
+			indicatorTop() {
+				const {
+					top,
+					itemHeight
+				} = this.letterInfo
+				return Math.floor(top + itemHeight * this.activeIndex + itemHeight / 2 - this.indicatorHeight / 2)
+			}
+		},
+		watch: {
+			// ������������������������������������������������
+			uIndexList: {
+				immediate: true,
+				handler() {
+					uni.$u.sleep().then(() => {
+						this.setIndexListLetterInfo()
+					})
+				}
+			}
+		},
+		created() {
+			this.children = []
+			this.anchors = []
+			this.init()
+		},
+		mounted() {
+			this.setIndexListLetterInfo()
+		},
+		methods: {
+			init() {
+				// ���������������������������������������������
+				//������this.customNavHeight���������this.scrollViewHeight���������maxHeight
+				//���������u-index-list������������tabbar���������,scroll-view������������������������������
+				this.scrollViewHeight = this.sys.windowHeight - this.customNavHeight
+			},
+			// ���������������������
+			touchStart(e) {
+				// ���������������������
+				const touchStart = e.changedTouches[0]
+				if (!touchStart) return
+				this.touching = true
+				const {
+					pageY
+				} = touchStart
+				// ������������������������������������������������������������������������
+				const currentIndex = this.getIndexListLetter(pageY)
+				this.setValueForTouch(currentIndex)
+			},
+			// ������������������������������������
+			touchMove(e) {
+				// ���������������������
+				let touchMove = e.changedTouches[0]
+				if (!touchMove) return;
+
+				// ������������������������������������������������ touching ��� false ��������������� indicator ������
+				if (!this.touching) {
+					this.touching = true
+				}
+				const {
+					pageY
+				} = touchMove
+				const currentIndex = this.getIndexListLetter(pageY)
+				this.setValueForTouch(currentIndex)
+			},
+			// ������������
+			touchEnd(e) {
+				// ���������������������������������������������������������������������������������������������������������������u-transition���show���������������
+				uni.$u.sleep(300).then(() => {
+					this.touching = false
+				})
+			},
+			// ������������������������������������������������������������
+			getIndexListLetterRect() {
+				return new Promise(resolve => {
+					// ������������������������������dom������
+					// #ifndef APP-NVUE
+					this.$uGetRect('.u-index-list__letter').then(size => {
+						resolve(size)
+					})
+					// #endif
+
+					// #ifdef APP-NVUE
+					const ref = this.$refs['u-index-list__letter']
+					dom.getComponentRect(ref, res => {
+						resolve(res.size)
+					})
+					// #endif
+				})
+			},
+			// ������indexList���������������������
+			setIndexListLetterInfo() {
+				this.getIndexListLetterRect().then(size => {
+					const {
+						height
+					} = size
+					const sys = uni.$u.sys()
+					const windowHeight = sys.windowHeight
+					let customNavHeight = 0
+					// ���������������������������������������������������������������������������������������������������
+					if (this.customNavHeight == 0) {
+						// #ifdef H5
+						customNavHeight = sys.windowTop
+						// #endif
+						// #ifndef H5
+						// ������H5���������������������������������������������windowHeight���������������������������������������������������������������������������
+						customNavHeight = -(sys.statusBarHeight + 44)
+						// #endif
+					} else {
+						customNavHeight = uni.$u.getPx(this.customNavHeight)
+					}
+					this.letterInfo = {
+						height,
+						// ������������������������������������������������������������������������������������������������������������������������
+						top: (windowHeight - height) / 2 + customNavHeight / 2,
+						itemHeight: Math.floor(height / this.uIndexList.length)
+					}
+				})
+			},
+			// ������������������������������������
+			getIndexListLetter(pageY) {
+				const {
+					top,
+					height,
+					itemHeight
+				} = this.letterInfo
+				// ���H5���pageY���������������������������uni-app���������������H5���������������������������H5���������������������������������
+				// #ifdef H5
+				pageY += uni.$u.sys().windowTop
+				// #endif
+				// ���������������������������������������������������������������������������������������������������������������������������������
+				if (pageY < top) {
+					return 0
+				} else if (pageY >= top + height) {
+					// ���������������������������������������
+					return this.uIndexList.length - 1
+				} else {
+					// ���������������Y������������������������������������top������������������������������������������������������������������������������������
+					return Math.floor((pageY - top) / itemHeight);
+				}
+			},
+			// ������������������������������������������
+			setValueForTouch(currentIndex) {
+				// ������������������������������������������������������������������������������������������������
+				if (currentIndex === this.activeIndex) return
+				this.activeIndex = currentIndex
+				// #ifndef APP-NVUE || MP-WEIXIN
+				// ������nvue������������anchor���item������u-index-item���������������������index-item������������
+				this.scrollIntoView = `u-index-item-${this.uIndexList[currentIndex].charCodeAt(0)}`
+				// #endif
+				// #ifdef MP-WEIXIN
+				// ���������������������scroll-view���scroll-into-view���������������slot���������������id���������������������������scrollTop���������������������������
+				this.scrollTop = this.children[currentIndex].top
+				// #endif
+				// #ifdef APP-NVUE
+				// ���nvue������������cell���header������������������������������������������header(anchor)������������
+				const anchor = `u-index-anchor-${this.uIndexList[currentIndex]}`
+				dom.scrollToElement(this.anchors[currentIndex].$refs[anchor], {
+					offset: 0,
+					animated: false
+				})
+				// #endif
+			},
+			getHeaderRect() {
+				// ������header slot������������������list���������������������������������������top������
+				return new Promise(resolve => {
+					dom.getComponentRect(this.$refs.header, res => {
+						resolve(res.size)
+					})
+				})
+			},
+			// scroll-view���������������
+			async scrollHandler(e) {
+				if (this.touching || this.scrolling) return
+				// ������������������������������������������������������������������������������
+				this.scrolling = true
+				uni.$u.sleep(10).then(() => {
+					this.scrolling = false
+				})
+				let scrollTop = 0
+				const len = this.children.length
+				let children = this.children
+				const anchors = this.anchors
+				// #ifdef APP-NVUE
+				// nvue���������������������������������������������������������
+				scrollTop = Math.abs(e.contentOffset.y)
+				// ������header slot���������������
+				const header = await this.getHeaderRect()
+				// item���top���������nvue������������������anchor���top������������nvue������index-item���top
+				let top = header.height
+				// ������list������������������cell���top������������������header slot���������item���������height���������������������nvue������������������
+				children = this.children.map((item, index) => {
+					const child = {
+						height: item.height,
+						top
+					}
+					// ���������������������������item������������������
+					top += item.height + anchors[index].height
+					return child
+				})
+				// #endif
+				// #ifndef APP-NVUE
+				// ���nvue������detail���������������������
+				scrollTop = e.detail.scrollTop
+				// #endif
+				for (let i = 0; i < len; i++) {
+					const item = children[i],
+						nextItem = children[i + 1]
+					// ������������������������������������item���top���������������������������������������������
+					if (scrollTop <= children[0].top || scrollTop >= children[len - 1].top + children[len -
+							1].height) {
+						this.activeIndex = -1
+						break
+					} else if (!nextItem) { 
+						// ���������������������item���������������������������������������
+						this.activeIndex = len - 1
+						break
+					} else if (scrollTop > item.top && scrollTop < nextItem.top) {
+						this.activeIndex = i
+						break
+					}
+				}
+			},
+		},
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import "../../libs/css/components.scss";
+
+	.u-index-list {
+
+		&__letter {
+			position: fixed;
+			right: 0;
+			text-align: center;
+			z-index: 3;
+			padding: 0 6px;
+
+			&__item {
+				width: 16px;
+				height: 16px;
+				border-radius: 100px;
+				margin: 1px 0;
+				@include flex;
+				align-items: center;
+				justify-content: center;
+
+				&--active {
+					background-color: $u-primary;
+				}
+
+				&__index {
+					font-size: 12px;
+					text-align: center;
+					line-height: 12px;
+				}
+			}
+		}
+
+		&__indicator {
+			width: 50px;
+			height: 50px;
+			border-radius: 100px 100px 0 100px;
+			text-align: center;
+			color: #ffffff;
+			background-color: #c9c9c9;
+			transform: rotate(-45deg);
+			@include flex;
+			justify-content: center;
+			align-items: center;
+
+			&__text {
+				font-size: 28px;
+				line-height: 28px;
+				font-weight: bold;
+				color: #fff;
+				transform: rotate(45deg);
+				text-align: center;
+			}
+		}
+	}
+</style>

--
Gitblit v1.8.0