2025/2/8第一次更新

This commit is contained in:
爱吃咸鱼小猫咪
2025-02-08 18:50:38 +08:00
commit d7af560866
26519 changed files with 5046029 additions and 0 deletions
@@ -0,0 +1,2 @@
export * from './scroll-list-custom'
export * from './use-scroll-list'
@@ -0,0 +1,78 @@
import { computed, toRef } from 'vue'
import { useComponentColor, useNamespace } from '../../../../hooks'
import { formatDomSizeValue } from '../../../../utils'
import type { CSSProperties } from 'vue'
import type { ScrollListProps } from '../scroll-list'
export const useScrollListCustomStyle = (props: ScrollListProps) => {
const ns = useNamespace('scroll-list')
// 解析颜色
const [indicatorColorClass, indicatorColorStyle] = useComponentColor(
toRef(props, 'indicatorColor'),
'bg'
)
const [indicatorBlockColorClass, indicatorBlockColorStyle] =
useComponentColor(toRef(props, 'indicatorBlockColor'), 'bg')
// 指示器对应的类
const indicatorClass = computed<string>(() => {
const cls: string[] = [ns.e('indicator')]
if (indicatorColorClass.value) cls.push(indicatorColorClass.value)
return cls.join(' ')
})
// 指示器的样式
const indicatorStyle = computed<CSSProperties>(() => {
const style: CSSProperties = {}
if (props.indicatorWidth)
style.width = formatDomSizeValue(props.indicatorWidth, 'px')
if (!indicatorColorClass.value) {
style.backgroundColor =
indicatorColorStyle.value || 'var(--tn-color-gray-disabled)'
}
return style
})
// 指示器滑块对应的类
const indicatorBlockClass = computed<string>(() => {
const cls: string[] = [ns.e('indicator-block')]
if (indicatorBlockColorClass.value) cls.push(indicatorBlockColorClass.value)
return cls.join(' ')
})
// 指示器滑块的样式
const indicatorBlockStyle = computed<(distance: number) => CSSProperties>(
() => {
return (distance: number) => {
const style: CSSProperties = {}
if (props.indicatorBlockWidth)
style.width = formatDomSizeValue(props.indicatorBlockWidth, 'px')
style.left = `${distance}px`
if (!indicatorBlockColorClass.value) {
style.backgroundColor =
indicatorBlockColorStyle.value || 'var(--tn-color-primary)'
}
return style
}
}
)
return {
ns,
indicatorClass,
indicatorStyle,
indicatorBlockClass,
indicatorBlockStyle,
}
}
@@ -0,0 +1,85 @@
import { getCurrentInstance, nextTick, onMounted, ref } from 'vue'
import { useSelectorQuery } from '../../../../hooks'
import { debugWarn, generateId } from '../../../../utils'
import type { SetupContext } from 'vue'
import type { ScrollListEmits, ScrollListProps } from '../scroll-list'
export const useScrollList = (
props: ScrollListProps,
emits: SetupContext<ScrollListEmits>['emit']
) => {
const instance = getCurrentInstance()
if (!instance) {
debugWarn('TnScrollList', '请在setup函数中使用useScrollList')
}
// 内容容器id
const componentId = `tsl-${generateId()}`
const componentContentId = `${componentId}-content`
const { getSelectorNodeInfo } = useSelectorQuery(instance)
// 内容容器的宽度
let componentWidth = 0
let comoponentContentWidth = 0
// 滑块滑动的距离
const indicatorBlockScrollDistance = ref<number>(0)
let initCount = 0
// 获取内容容器的宽度
const getContentRectInfo = async () => {
try {
const componentRectInfo = await getSelectorNodeInfo(`#${componentId}`)
const contentRectInfo = await getSelectorNodeInfo(
`#${componentContentId}`
)
initCount = 0
componentWidth = componentRectInfo.width || 0
comoponentContentWidth = contentRectInfo.width || 0
} catch (err) {
if (initCount > 10) {
initCount = 0
debugWarn('TnScrollList', `获取内容容器的宽度失败: ${err}`)
return
}
initCount++
setTimeout(() => {
getContentRectInfo()
}, 150)
}
}
// scrollView滚动事件
const scrollViewScrollEvent = (e: any) => {
const scrollLeft = e.detail.scrollLeft
indicatorBlockScrollDistance.value =
(scrollLeft * (props.indicatorWidth - props.indicatorBlockWidth)) /
(comoponentContentWidth - componentWidth)
}
// scrollView滚动到最左边触发
const scrollToLeftEvent = () => {
emits('scroll-left')
}
// scrollView滚动到最右边触发
const scrollToRightEvent = () => {
emits('scroll-right')
}
onMounted(() => {
nextTick(() => {
getContentRectInfo()
})
})
return {
componentId,
componentContentId,
indicatorBlockScrollDistance,
scrollViewScrollEvent,
scrollToLeftEvent,
scrollToRightEvent,
}
}
@@ -0,0 +1,3 @@
import type ScrollList from './scroll-list.vue'
export type TnScrollListInstance = InstanceType<typeof ScrollList>
@@ -0,0 +1,49 @@
import { buildProps } from '../../../utils'
import type { ExtractPropTypes } from 'vue'
export const scrollListProps = buildProps({
/**
* @description 是否显示指示器
*/
indicator: {
type: Boolean,
default: true,
},
/**
* @description 指示器的宽度,单位 px
*/
indicatorWidth: {
type: Number,
default: 40,
},
/**
* @description 指示器滑块的宽度,单位 px
*/
indicatorBlockWidth: {
type: Number,
default: 20,
},
/**
* @description 指示器的背景颜色,以tn开头使用图鸟内置的颜色
*/
indicatorColor: String,
/**
* @description 指示器滑块的背景颜色,以tn开头使用图鸟内置的颜色
*/
indicatorBlockColor: String,
})
export const scrollListEmits = {
/**
* @description 滚动到左边时触发
*/
'scroll-left': () => true,
/**
* @description 滚动到右边时触发
*/
'scroll-right': () => true,
}
export type ScrollListProps = ExtractPropTypes<typeof scrollListProps>
export type ScrollListEmits = typeof scrollListEmits
@@ -0,0 +1,55 @@
<script lang="ts" setup>
import { scrollListEmits, scrollListProps } from './scroll-list'
import { useScrollList, useScrollListCustomStyle } from './composables'
const props = defineProps(scrollListProps)
const emits = defineEmits(scrollListEmits)
const {
componentId,
componentContentId,
indicatorBlockScrollDistance,
scrollViewScrollEvent,
scrollToLeftEvent,
scrollToRightEvent,
} = useScrollList(props, emits)
const {
ns,
indicatorClass,
indicatorStyle,
indicatorBlockClass,
indicatorBlockStyle,
} = useScrollListCustomStyle(props)
</script>
<template>
<view :id="componentId" :class="[ns.b(), ns.is('indicator', indicator)]">
<!-- 内容 -->
<view :class="[ns.e('content')]">
<scroll-view
:class="[ns.e('scroll-view')]"
scroll-x
@scroll="scrollViewScrollEvent"
@scrolltoupper="scrollToLeftEvent"
@scrolltolower="scrollToRightEvent"
>
<view :id="componentContentId" class="data">
<slot />
</view>
</scroll-view>
</view>
<!-- 指示器 -->
<view v-if="indicator" :class="[indicatorClass]" :style="indicatorStyle">
<!-- 滑块 -->
<view
:class="[indicatorBlockClass]"
:style="indicatorBlockStyle(indicatorBlockScrollDistance)"
/>
</view>
</view>
</template>
<style lang="scss" scoped>
@import '../../../theme-chalk/src/scroll-list.scss';
</style>