feat: 文档图片可放大
This commit is contained in:
parent
934f7f79a6
commit
3630f18551
|
|
@ -58,12 +58,19 @@
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<main v-loading="loading" class="docs-main">
|
<main v-loading="loading" class="docs-main" @click="handleArticleClick">
|
||||||
<div v-if="loadError" class="docs-error">
|
<div v-if="loadError" class="docs-error">
|
||||||
<el-empty :description="loadError" />
|
<el-empty :description="loadError" />
|
||||||
</div>
|
</div>
|
||||||
<article v-else class="docs-article" v-html="renderedHtml" />
|
<article v-else class="docs-article" v-html="renderedHtml" />
|
||||||
</main>
|
</main>
|
||||||
|
<el-image-viewer
|
||||||
|
v-if="previewVisible"
|
||||||
|
:url-list="previewUrls"
|
||||||
|
:initial-index="previewIndex"
|
||||||
|
hide-on-click-modal
|
||||||
|
@close="previewVisible = false"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -96,6 +103,9 @@ const loadError = ref('')
|
||||||
const keyword = ref('')
|
const keyword = ref('')
|
||||||
const toc = ref<TocItem[]>([])
|
const toc = ref<TocItem[]>([])
|
||||||
const searchSections = ref<SearchSection[]>([])
|
const searchSections = ref<SearchSection[]>([])
|
||||||
|
const previewVisible = ref(false)
|
||||||
|
const previewIndex = ref(0)
|
||||||
|
const previewUrls = computed(() => extractImageUrls(rawMarkdown.value, activeDocPath.value))
|
||||||
|
|
||||||
const renderedHtml = computed(() => renderMarkdown(rawMarkdown.value, activeDocPath.value))
|
const renderedHtml = computed(() => renderMarkdown(rawMarkdown.value, activeDocPath.value))
|
||||||
const level3Toc = computed(() => toc.value.filter((item) => item.level === 3))
|
const level3Toc = computed(() => toc.value.filter((item) => item.level === 3))
|
||||||
|
|
@ -221,7 +231,7 @@ function renderMarkdown(markdown: string, docPath: string) {
|
||||||
if (image) {
|
if (image) {
|
||||||
const alt = escapeHtml(image[1])
|
const alt = escapeHtml(image[1])
|
||||||
const src = escapeHtml(resolveDocAsset(docPath, image[2]))
|
const src = escapeHtml(resolveDocAsset(docPath, image[2]))
|
||||||
html.push(`<figure><img src="${src}" alt="${alt}" loading="lazy" /><figcaption>${alt}</figcaption></figure>`)
|
html.push(`<figure><img class="doc-preview-image" src="${src}" alt="${alt}" loading="lazy" data-preview-src="${src}" /><figcaption>${alt}</figcaption></figure>`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -243,6 +253,14 @@ function resolveDocAsset(docPath: string, assetPath: string) {
|
||||||
return `${getDocsBase()}${encodeURI(normalized)}`
|
return `${getDocsBase()}${encodeURI(normalized)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function extractImageUrls(markdown: string, docPath: string) {
|
||||||
|
return markdown
|
||||||
|
.split('\n')
|
||||||
|
.map((line) => /^!\[[^\]]*]\(([^)]+)\)$/.exec(line.trim())?.[1])
|
||||||
|
.filter((src): src is string => Boolean(src))
|
||||||
|
.map((src) => resolveDocAsset(docPath, src))
|
||||||
|
}
|
||||||
|
|
||||||
function buildHeadingId(text: string, counters: Map<string, number>) {
|
function buildHeadingId(text: string, counters: Map<string, number>) {
|
||||||
const base = text
|
const base = text
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
|
|
@ -282,6 +300,15 @@ function jumpTo(id: string) {
|
||||||
document.getElementById(id)?.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
document.getElementById(id)?.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleArticleClick(event: MouseEvent) {
|
||||||
|
const target = event.target
|
||||||
|
if (!(target instanceof HTMLImageElement)) return
|
||||||
|
const src = target.dataset.previewSrc
|
||||||
|
if (!src) return
|
||||||
|
previewIndex.value = Math.max(previewUrls.value.indexOf(src), 0)
|
||||||
|
previewVisible.value = true
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
@ -511,6 +538,10 @@ function jumpTo(id: string) {
|
||||||
background: #f5f7fa;
|
background: #f5f7fa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:deep(.docs-article .doc-preview-image) {
|
||||||
|
cursor: zoom-in;
|
||||||
|
}
|
||||||
|
|
||||||
:deep(.docs-article figcaption) {
|
:deep(.docs-article figcaption) {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
color: #909399;
|
color: #909399;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue