chore: add vitepress doc custom theme
This commit is contained in:
parent
4e10e65216
commit
340926bcd3
85
docs/.vitepress/theme/DynamicAds.vue
Normal file
85
docs/.vitepress/theme/DynamicAds.vue
Normal file
@ -0,0 +1,85 @@
|
||||
<!-- 在vitepress右侧的目录导航中插入动态广告组件-->
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted } from 'vue'
|
||||
|
||||
const ads = ref([])
|
||||
const currentAdIndex = ref(0)
|
||||
let intervalId = null
|
||||
|
||||
const fetchAds = async () => {
|
||||
return [
|
||||
{
|
||||
id: 1,
|
||||
imageUrl: 'https://mangoproxy.com/assetsfile/images/logomango.webp',
|
||||
landingUrl: 'https://mangoproxy.com/?utm_source=mediacrawler&utm_medium=repository&utm_campaign=default',
|
||||
text: '全局IP代理白金推荐,支持210+国家'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const nextAd = () => {
|
||||
currentAdIndex.value = (currentAdIndex.value + 1) % ads.value.length
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
ads.value = await fetchAds()
|
||||
intervalId = setInterval(nextAd, 3000)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (intervalId) clearInterval(intervalId)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="vp-ad-carousel">
|
||||
<template v-if="ads.length > 0">
|
||||
<div class="ad-content">
|
||||
<a :href="ads[currentAdIndex].landingUrl" target="_blank" rel="noopener noreferrer">
|
||||
<img :src="ads[currentAdIndex].imageUrl" :alt="ads[currentAdIndex].text" class="ad-image">
|
||||
<p class="ad-text">{{ ads[currentAdIndex].text }}</p>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
<p v-else class="loading">Loading ads...</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.vp-ad-carousel {
|
||||
margin-top: 1rem;
|
||||
padding: 1rem;
|
||||
background-color: var(--vp-c-bg-soft);
|
||||
border-radius: 8px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.ad-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.ad-image {
|
||||
max-width: 130px;
|
||||
height: auto;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.ad-text {
|
||||
text-align: center;
|
||||
color: var(--vp-c-text-1);
|
||||
}
|
||||
|
||||
.loading {
|
||||
text-align: center;
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
</style>
|
14
docs/.vitepress/theme/MyLayout.vue
Normal file
14
docs/.vitepress/theme/MyLayout.vue
Normal file
@ -0,0 +1,14 @@
|
||||
<!--.vitepress/theme/MyLayout.vue-->
|
||||
<script setup>
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
import DynamicAds from './DynamicAds.vue'
|
||||
const { Layout } = DefaultTheme
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Layout>
|
||||
<template #aside-bottom>
|
||||
<DynamicAds />
|
||||
</template>
|
||||
</Layout>
|
||||
</template>
|
9
docs/.vitepress/theme/custom.css
Normal file
9
docs/.vitepress/theme/custom.css
Normal file
@ -0,0 +1,9 @@
|
||||
/* .vitepress/theme/custom.css */
|
||||
/**
|
||||
* Component: Sidebar
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
:root {
|
||||
--vp-sidebar-width: 285px;
|
||||
--vp-sidebar-bg-color: var(--vp-c-bg-alt);
|
||||
}
|
9
docs/.vitepress/theme/index.js
Normal file
9
docs/.vitepress/theme/index.js
Normal file
@ -0,0 +1,9 @@
|
||||
// .vitepress/theme/index.js
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
import MyLayout from './MyLayout.vue'
|
||||
|
||||
export default {
|
||||
extends: DefaultTheme,
|
||||
// 使用注入插槽的包装组件覆盖 Layout
|
||||
Layout: MyLayout
|
||||
}
|
Loading…
Reference in New Issue
Block a user