feat: 优化首页折叠面板实现
This commit is contained in:
1 parent
f90b8382d5
commit
d6b19cc230
2 files changed
+108
-10
No files matched your search
@@ -0,0 +1,94 @@
|
|||||||
|
<template>
|
||||||
|
<div class="miao-collapse-warpper" ref="cwRef" :style="cwStyle">
|
||||||
|
<div class="miao-collapse" ref="cRef" :style="cStyle">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const props = defineProps({
|
||||||
|
show: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const cwRef = ref<HTMLDivElement>()
|
||||||
|
const cRef = ref<HTMLDivElement>()
|
||||||
|
const cwStyle = ref<{ [key: string]: string | number }>({
|
||||||
|
maxHeight: '99999vh',
|
||||||
|
})
|
||||||
|
const cStyle = ref<{ [key: string]: string | number }>({})
|
||||||
|
|
||||||
|
let originHeight = -1
|
||||||
|
|
||||||
|
let timer: any[] = []
|
||||||
|
|
||||||
|
const clearTimer = () => {
|
||||||
|
timer.forEach((item) => {
|
||||||
|
clearTimeout(item)
|
||||||
|
})
|
||||||
|
timer = []
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleHide = () => {
|
||||||
|
clearTimer()
|
||||||
|
cwStyle.value = {
|
||||||
|
maxHeight: 0,
|
||||||
|
opacity: 0,
|
||||||
|
}
|
||||||
|
timer.push(setTimeout(() => {
|
||||||
|
cwStyle.value = {
|
||||||
|
maxHeight: 0,
|
||||||
|
display: 'none',
|
||||||
|
opacity: 0,
|
||||||
|
}
|
||||||
|
}, 300))
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleShow = () => {
|
||||||
|
clearTimer()
|
||||||
|
cwStyle.value = {
|
||||||
|
maxHeight: 0,
|
||||||
|
opacity: 0,
|
||||||
|
}
|
||||||
|
timer.push(setTimeout(() => {
|
||||||
|
cwStyle.value = {
|
||||||
|
maxHeight: `${originHeight}px`,
|
||||||
|
opacity: 1,
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => props.show, (newVal) => {
|
||||||
|
if (cwRef.value && cRef.value) {
|
||||||
|
if (newVal) {
|
||||||
|
handleShow()
|
||||||
|
} else {
|
||||||
|
handleHide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
originHeight = cwRef.value!.clientHeight
|
||||||
|
cwStyle.value = {
|
||||||
|
maxHeight: `${originHeight}px`,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.miao-collapse-warpper {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: end;
|
||||||
|
opacity: 1;
|
||||||
|
transition: all 0.3s ease-in-out, opacity 0.2s ease-in-out;
|
||||||
|
|
||||||
|
.miao-collapse {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
+14
-10
@@ -16,17 +16,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</miao-divider-left>
|
</miao-divider-left>
|
||||||
</div>
|
</div>
|
||||||
<div :class="['content-items-wrap', item.show ? '' : 'content-items-wrap-hide']">
|
<miao-collapse :show="item.show">
|
||||||
<div v-for="(cItem) in item.content" :key="cItem.name" class="content-item">
|
<div :class="['content-items-wrap']">
|
||||||
<div class="content-item-name">{{ cItem.name }}</div>
|
<div v-for="(cItem) in item.content" :key="cItem.name" class="content-item">
|
||||||
<div class="content-item-description">{{ cItem.description }}</div>
|
<div class="content-item-name">{{ cItem.name }}</div>
|
||||||
<div class="content-item-link-wrap">
|
<div class="content-item-description">{{ cItem.description }}</div>
|
||||||
<div class="content-item-link-wrap-icon"> <link-icon /></div>
|
<div class="content-item-link-wrap">
|
||||||
<a v-for="link in (cItem.links ?? [])" :href="link.url" target="_blank">{{ link.name }}</a>
|
<div class="content-item-link-wrap-icon"> <link-icon /></div>
|
||||||
<NuxtLink v-for="link in (cItem.nuxtLinks ?? [])" :to="link.to">{{ link.name }}</NuxtLink>
|
<a v-for="link in (cItem.links ?? [])" :href="link.url" target="_blank">{{ link.name }}</a>
|
||||||
|
<NuxtLink v-for="link in (cItem.nuxtLinks ?? [])" :to="link.to">{{ link.name }}</NuxtLink>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</miao-collapse>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -38,6 +40,7 @@ import miaoDividerLeft from '~/components/miaoDivider-left.vue';
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import ChevronDown from "~/components/icons/chevronDown.vue";
|
import ChevronDown from "~/components/icons/chevronDown.vue";
|
||||||
import linkIcon from '~/components/icons/link.vue';
|
import linkIcon from '~/components/icons/link.vue';
|
||||||
|
import miaoCollapse from '~/components/miaoCollapse.vue';
|
||||||
|
|
||||||
type PageContent = {
|
type PageContent = {
|
||||||
subTitle: string,
|
subTitle: string,
|
||||||
@@ -239,6 +242,7 @@ const switchItemShow = (item: PageContent) => {
|
|||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
// align-items: end;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
// overflow: hidden;
|
// overflow: hidden;
|
||||||
transition: max-height 0.25s ease, opacity 0.25s ease;
|
transition: max-height 0.25s ease, opacity 0.25s ease;
|
||||||
@@ -247,7 +251,7 @@ const switchItemShow = (item: PageContent) => {
|
|||||||
// margin: 0 -20px;
|
// margin: 0 -20px;
|
||||||
&-hide {
|
&-hide {
|
||||||
max-height: 0;
|
max-height: 0;
|
||||||
opacity: 0;
|
// opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user