chat-app/src/uni_modules/tmui/components/tm-tabs-pane/tm-tabs-pane.vue
scout b54bfe63ad
Some checks are pending
Check / lint (push) Waiting to run
Check / typecheck (push) Waiting to run
Check / build (build, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build, 18.x, windows-latest) (push) Waiting to run
Check / build (build:app, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build:app, 18.x, windows-latest) (push) Waiting to run
Check / build (build:mp-weixin, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build:mp-weixin, 18.x, windows-latest) (push) Waiting to run
init
2024-11-11 14:46:14 +08:00

295 lines
7.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<tm-sheet
v-if="tabsSwiper || (!tabsSwiper && isShowRender)"
:transprent="props.transprent"
:color="props.color"
:followTheme="props.followTheme"
:followDark="props.followDark"
:dark="props.dark"
:round="props.round"
:shadow="props.shadow"
:outlined="props.outlined"
:border="props.border"
:borderStyle="props.borderStyle"
:borderDirection="props.borderDirection"
:text="props.text"
:linear="props.linear"
:linearDeep="props.linearDeep"
:_style="props._style"
:_class="props._class"
:eventPenetrationEnabled="true"
:margin="[0, 0]"
:padding="[0, 0]"
:width="_width"
:height="_height"
>
<view
v-if="sc_top < -30 && reFresh != 0 && !tabsSwiperDisAbledPull"
:style="{
top: (reFresh == 2 ? -refreshJuli / 2 : -sc_top - 30) + 'px',
width: _width + 'rpx'
}"
class="zIndex-17 absolute l-0 flex flex-row flex-row-center-center"
>
<view class="pr-32">
<tm-icon v-if="sc_top > refreshJuli && reFresh != 2" name="tmicon-long-arrow-down"></tm-icon>
<tm-icon v-if="sc_top <= refreshJuli && reFresh != 2" name="tmicon-long-arrow-up"></tm-icon>
<tm-icon v-if="reFresh == 2" spin name="tmicon-shuaxin"></tm-icon>
</view>
<view>
<tm-text v-if="sc_top > refreshJuli" _class="text-align-center" label="下拉刷新"></tm-text>
<tm-text v-if="sc_top <= refreshJuli" _class="text-align-center" label="松开立即刷新"></tm-text>
<tm-text _class="text-align-center" label="更新于今日8:30"></tm-text>
</view>
</view>
<scroll-view
@scrolltolower="onScrollBootom"
@scroll="onScroll"
:scroll-y="_height ? true : false"
enable-flex
class="flex-col"
:style="[{ width: _width + 'rpx' }, _height ? { height: _height + 'rpx' } : '']"
>
<view
@touchStart="onScrollStart"
@touchend="onScrollEnd"
v-if="isShowRender"
:style="{ transform: `translateY(${reFresh == 2 ? -refreshJuli : 0}px)` }"
class="flex contentx"
>
<slot></slot>
</view>
</scroll-view>
</tm-sheet>
</template>
<script lang="ts" setup>
/**
* 选项卡面板
* @description 不可以单独使用必须放置在tm-tabs组件中使用。
*/
import tmSheet from '../tm-sheet/tm-sheet.vue'
import tmTabs from '../tm-tabs/tm-tabs.vue'
import tmIcon from '../tm-icon/tm-icon.vue'
import tmText from '../tm-text/tm-text.vue'
import { tabsobj } from '../tm-tabs/interface'
import { Ref, ref, computed, watch, onUnmounted, inject, ComputedRef, getCurrentInstance, ComponentInternalInstance, PropType, onMounted } from 'vue'
import { custom_props } from '../../tool/lib/minxs'
const tabs = ref<InstanceType<typeof tmTabs> | null>(null)
const proxy = getCurrentInstance()?.proxy ?? null
const props = defineProps({
...custom_props,
transprent: {
type: [Boolean, String],
default: false
},
color: {
type: String,
default: 'white'
},
//是否显示红点与count不能同时出现
dot: {
type: Boolean,
default: false
},
count: {
type: [String, Number],
default: ''
},
//红点颜色
dotColor: {
type: String,
default: 'red'
},
name: {
type: [String, Number],
default: '',
required: true
},
title: {
type: String,
default: ''
},
icon: {
type: String,
default: ''
},
pullFun: {
type: [Function] as PropType<(type: 'top' | 'bottom') => boolean>,
default: () => {
return (type: 'top' | 'bottom') => {
return true
}
}
}
})
//---scroll下拉刷新---------
//0未初始化/松手可能未被触发没有达到刷新的条件即被中止了1下拉手势中还未放开手。2松开手触发下拉刷新3复位刷新完成
type reFreshType = 0 | 1 | 2 | 3
const sc_top = ref(0)
const refreshJuli = -100 //达到120才能被刷新
const reFresh: Ref<reFreshType> = ref(0)
const isyesResh = ref(false) //是否达到了规定刷新条件。
const isUpToogle = ref(true) //手指是否放开。
//---------------
const _pname = computed(() => String(props.name))
//父级方法。
let parent: any = proxy?.$parent
while (parent) {
if (parent?.tmTabsId == 'tmTabsId' || !parent) {
break
} else {
parent = parent?.$parent ?? null
}
}
if (typeof _pname.value != 'undefined' && _pname.value != '') {
parent?.pushKey({
key: _pname.value,
title: props.title,
icon: props.icon,
dot: props.dot,
count: props.count,
dotColor: props.dotColor
})
}
const _width = inject(
'tabsWidth',
computed(() => 0)
)
const _height = inject(
'tabsheight',
computed(() => 0)
)
const tabsActiveName: ComputedRef<string | number | undefined> = inject(
'tabsActiveName',
computed(() => undefined)
)
const tabsActiveCacheTabse = inject(
'tabsActiveCacheTabse',
computed<Array<tabsobj>>(() => {
return []
})
)
const tabsSwiper = inject(
'tabsSwiper',
computed(() => false)
)
const tabsSwiperIsMoveing = inject(
'tabsSwiperIsMoveing',
computed(() => false)
)
const tabsSwiperDisAbledPull = inject(
'tabsSwiperDisAbledPull',
computed(() => true)
)
const activeIndex = inject(
'tabsActiveactiveIndex',
computed(() => 0)
)
// const selfIndex = computed(()=>tabsActiveCacheTabse.value.findIndex(el=>el.key==tabsActiveName.value))
const selfIndex = computed(() => tabsActiveCacheTabse.value.findIndex((el) => el.key == _pname.value))
const isShowRender = computed(() => {
if (tabsSwiper.value == false) {
return selfIndex.value == activeIndex.value
}
return selfIndex.value >= activeIndex.value - 1 && selfIndex.value <= activeIndex.value + 1
})
watch([() => props.title, () => props.icon, () => props.dot, () => props.dotColor, () => props.count], () => {
parent?.setTitle({
key: _pname.value,
title: props.title,
icon: props.icon,
dot: props.dot,
count: props.count,
dotColor: props.dotColor
})
})
onUnmounted(() => {
parent?.unbindKey(_pname.value)
})
//=====
function onScroll(e: any) {
// 切换页面中不允许下拉。
if (tabsSwiperIsMoveing.value) return
if (reFresh.value == 2 && isUpToogle.value) return
if (sc_top.value <= refreshJuli) {
isyesResh.value = true
} else {
isyesResh.value = false
}
sc_top.value = e.detail.scrollTop
reFresh.value = 1
}
function onScrollStart() {
// 切换页面中不允许下拉。
if (tabsSwiperIsMoveing.value) return
isUpToogle.value = false
}
async function onScrollEnd() {
// 切换页面中不允许下拉。
if (tabsSwiperIsMoveing.value) return
isUpToogle.value = true
if (reFresh.value == 2) return
if (isyesResh.value) {
let p = await funPull('top')
if (p) {
reFresh.value = 0
} else {
isUpToogle.value = false
}
} else {
reFresh.value = 0
}
}
async function onScrollBootom() {
// 切换页面中不允许下拉。
if (tabsSwiperIsMoveing.value) return
isUpToogle.value = true
if (reFresh.value == 2) return
if (isyesResh.value) {
let p = await funPull('bottom')
if (p) {
reFresh.value = 0
} else {
isUpToogle.value = false
}
} else {
reFresh.value = 0
}
}
async function funPull(type: 'top' | 'bottom') {
if (typeof props.pullFun === 'function') {
uni.showLoading({
title: '...',
mask: true
})
let p = await props.pullFun(type)
if (typeof p === 'function') {
p = await p(type)
}
uni.hideLoading()
return p
}
}
</script>
<style scoped>
.contentx {
transition-duration: 0.5s;
transition-timing-function: ease;
transition-delay: 0s;
transform: translateY(0px);
transition-property: transform, top;
}
</style>