mirror of
https://github.com/Moe-Sakura/frontend.git
synced 2026-04-18 21:29:18 +08:00
- Integrated custom JavaScript and HTML functionality into the application, allowing users to apply their scripts and markup dynamically. - Updated API configuration handling in search.ts to utilize settings from the store, improving flexibility and maintainability. - Refactored theme application logic to ensure custom styles are applied correctly during component lifecycle events. - Improved the user interface in SettingsModal.vue with an IDE-style code editor for better user experience when editing custom code.
66 lines
1.5 KiB
Vue
66 lines
1.5 KiB
Vue
<script setup lang="ts">
|
|
import { ref, onMounted, onUnmounted } from 'vue'
|
|
|
|
const props = defineProps<{
|
|
/** 距离可视区多少像素时开始渲染 */
|
|
rootMargin?: string
|
|
/** 是否只渲染一次(进入后不再隐藏) */
|
|
once?: boolean
|
|
/** 占位高度 */
|
|
minHeight?: string
|
|
}>()
|
|
|
|
const isVisible = ref(false)
|
|
const containerRef = ref<HTMLElement | null>(null)
|
|
let observer: IntersectionObserver | null = null
|
|
|
|
onMounted(() => {
|
|
if (!containerRef.value) {return}
|
|
|
|
observer = new IntersectionObserver(
|
|
(entries) => {
|
|
entries.forEach((entry) => {
|
|
if (entry.isIntersecting) {
|
|
isVisible.value = true
|
|
// 如果是一次性渲染,观察到后就停止
|
|
if (props.once && observer && containerRef.value) {
|
|
observer.unobserve(containerRef.value)
|
|
}
|
|
} else if (!props.once) {
|
|
isVisible.value = false
|
|
}
|
|
})
|
|
},
|
|
{
|
|
rootMargin: props.rootMargin || '200px 0px', // 提前 200px 开始渲染
|
|
threshold: 0,
|
|
},
|
|
)
|
|
|
|
observer.observe(containerRef.value)
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
if (observer) {
|
|
observer.disconnect()
|
|
observer = null
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
ref="containerRef"
|
|
:style="{ minHeight: !isVisible ? (minHeight || '60px') : undefined }"
|
|
>
|
|
<slot v-if="isVisible" />
|
|
<!-- 占位符 -->
|
|
<div
|
|
v-else
|
|
class="animate-pulse bg-gray-200/50 dark:bg-slate-700/50 rounded-xl"
|
|
:style="{ height: minHeight || '60px' }"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|