forked from boos/BoosAPI
ef1962d10b
* rename site api request wording * replace real site example domains
7.9 KiB
7.9 KiB
layout, hero, features
| layout | hero | features | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| home |
|
|
项目架构
项目界面预览
<style> .home-architecture { max-width: 800px; margin: 0 auto; } .home-architecture img { width: 100%; border-radius: 16px; border: 1px solid var(--vp-c-divider); box-shadow: 0 12px 28px rgba(2, 8, 20, 0.08); } .home-carousel { position: relative; width: 100%; margin: 0; overflow: hidden; border: 1px solid var(--vp-c-divider); border-radius: 16px; background: var(--vp-c-bg-soft); box-shadow: 0 10px 24px rgba(2, 8, 20, 0.06); } .home-carousel-track { display: flex; width: 100%; transform: translateX(0%); transition: transform 420ms ease; will-change: transform; } .home-carousel-slide { flex: 0 0 100%; margin: 0; } .home-carousel-slide img { display: block; width: 100%; height: auto; max-height: min(78vh, 980px); object-fit: contain; background: var(--vp-c-bg); } .home-carousel-slide figcaption { padding: 12px 14px; font-size: 22px; line-height: 1.2; font-weight: 600; color: var(--vp-c-text-1); } .home-carousel-nav { position: absolute; top: 0; bottom: 0; width: 14%; border: 0; background: transparent; color: #fff; z-index: 2; display: flex; align-items: center; opacity: 0; transition: opacity 0.2s ease; cursor: pointer; } .home-carousel-nav span { display: inline-flex; width: 40px; height: 40px; border-radius: 999px; align-items: center; justify-content: center; background: rgba(17, 24, 39, 0.56); font-size: 28px; line-height: 1; user-select: none; } .home-carousel:hover .home-carousel-nav { opacity: 1; } .home-carousel-prev { left: 0; justify-content: flex-start; padding-left: 12px; background: linear-gradient(90deg, rgba(15, 23, 42, 0.2), transparent); } .home-carousel-next { right: 0; justify-content: flex-end; padding-right: 12px; background: linear-gradient(270deg, rgba(15, 23, 42, 0.2), transparent); } @media (max-width: 640px) { .home-carousel-slide figcaption { font-size: 18px; padding: 10px 12px; } .home-carousel-nav { opacity: 1; width: 18%; } .home-carousel-nav span { width: 34px; height: 34px; font-size: 24px; } } </style> <script setup> import { onBeforeUnmount, onMounted } from 'vue'; let disposeCarousel = null; onMounted(() => { const root = document.querySelector('.home-carousel'); if (!root) return; const track = root.querySelector('.home-carousel-track'); const slides = root.querySelectorAll('.home-carousel-slide'); const prevBtn = root.querySelector('.home-carousel-prev'); const nextBtn = root.querySelector('.home-carousel-next'); if (!track || slides.length === 0) return; const total = slides.length; let index = 0; let timerId = null; const render = () => { track.style.transform = `translateX(-${index * 100}%)`; }; const goNext = () => { index = (index + 1) % total; render(); }; const goPrev = () => { index = (index - 1 + total) % total; render(); }; const stopAutoPlay = () => { if (timerId !== null) { window.clearInterval(timerId); timerId = null; } }; const startAutoPlay = () => { stopAutoPlay(); timerId = window.setInterval(goNext, 3000); }; const onMouseEnter = () => stopAutoPlay(); const onMouseLeave = () => startAutoPlay(); const onPrevClick = () => { goPrev(); startAutoPlay(); }; const onNextClick = () => { goNext(); startAutoPlay(); }; root.addEventListener('mouseenter', onMouseEnter); root.addEventListener('mouseleave', onMouseLeave); prevBtn?.addEventListener('click', onPrevClick); nextBtn?.addEventListener('click', onNextClick); render(); startAutoPlay(); disposeCarousel = () => { stopAutoPlay(); root.removeEventListener('mouseenter', onMouseEnter); root.removeEventListener('mouseleave', onMouseLeave); prevBtn?.removeEventListener('click', onPrevClick); nextBtn?.removeEventListener('click', onNextClick); }; }); onBeforeUnmount(() => { if (typeof disposeCarousel === 'function') { disposeCarousel(); } }); </script>从这里开始
- 初次部署或首次接入:从 快速上手 开始,先跑通最小可用链路。
- 不确定上游平台该怎么选:先看 上游接入,再决定走
账号管理还是API Key管理。 - 准备上线或升级回滚:查看 部署指南 与 运维手册。
- 需要补齐环境变量或路由参数:直接查 配置说明。
- 正在处理客户端或第三方工具接入:优先看 客户端接入。
- 遇到高频报错或异常表现:去 常见问题 FAQ 快速定位根因。
文档维护入口
/保持为面向所有读者的公开落地页,不再承担维护说明或贡献说明的二次首页职责。- 维护文档站、梳理导航、补充内容地图时,请进入 文档维护与贡献。
- 新增 FAQ 或教程前,请先阅读 FAQ/教程贡献规范。








