添加微信分享功能

This commit is contained in:
2025-08-09 13:27:47 +08:00
parent f57e410393
commit 597339b666
7 changed files with 315 additions and 3 deletions

View File

@@ -9,7 +9,7 @@ export default defineAppConfig({
}
},
seo: {
siteName: 'Nuxt Docs Template'
siteName: 'Estel Docs'
},
header: {
title: 'Estel Docs',

View File

@@ -6,6 +6,15 @@ const { footer } = useAppConfig()
<UFooter>
<template #left>
{{ footer.credits }}
<UButton
color="neutral"
variant="ghost"
size="sm"
to="https://beian.miit.gov.cn/"
target="_blank"
>
陕ICP备2021012926号-3
</UButton>
</template>
<template #right>

View File

@@ -0,0 +1,96 @@
<script setup lang="ts">
import { onMounted } from 'vue'
const props = defineProps<{
url: string
title?: string
desc?: string
imgUrl?: string
}>()
// 仅在客户端挂载后执行,避免 SSR 阶段访问 window/location
onMounted(async () => {
try {
console.log('[WxShare] mounted with props:', { ...props })
await loadWxSdk()
console.log('[WxShare] wx sdk loaded:', !!(window as any).wx)
const { appId, timestamp, nonceStr, signature } = await getWxConfig()
console.log('[WxShare] got config:', { appId, timestamp, nonceStr, signature: signature.slice(0, 8) + '...' })
setupShare(appId, timestamp, nonceStr, signature)
} catch (err) {
console.error('[WxShare] init error:', err)
}
})
function loadWxSdk(): Promise<void> {
console.log('loadWxSdk')
if (typeof window === 'undefined') return Promise.resolve()
if ((window as any).wx) return Promise.resolve()
return new Promise((resolve, reject) => {
const existing = document.getElementById('wx-jssdk') as HTMLScriptElement | null
if (existing && (window as any).wx) return resolve()
const script = existing ?? document.createElement('script')
if (!existing) {
script.id = 'wx-jssdk'
script.src = 'https://res.wx.qq.com/open/js/jweixin-1.6.0.js'
script.async = true
script.onload = () => resolve()
script.onerror = () => reject(new Error('Failed to load jweixin.js'))
document.head.appendChild(script)
} else {
script.onload = () => resolve()
script.onerror = () => reject(new Error('Failed to load jweixin.js'))
}
})
}
async function getWxConfig(): Promise<{ appId: string, timestamp: number, nonceStr: string, signature: string }> {
const currentUrl = encodeURIComponent((location.href.split('#')[0]) || location.href)
return await $fetch('/api/wechat/wx-config', { params: { url: currentUrl } })
}
function setupShare(appId: string, timestamp: number, nonceStr: string, signature: string) {
const wx = (window as any).wx
const shareTitle = props.title || document.title || ''
const shareDesc = props.desc || document.title || ''
const shareLink = props.url
const shareImg = props.imgUrl || '/images/default-blog.jpg'
wx.config({
debug: false,
appId,
timestamp,
nonceStr,
signature,
jsApiList: ['updateTimelineShareData', 'updateAppMessageShareData']
})
wx.ready(() => {
console.log('[WxShare] wx.ready')
wx.updateTimelineShareData({
title: shareTitle,
link: shareLink,
imgUrl: shareImg,
success: () => {}
})
wx.updateAppMessageShareData({
title: shareTitle,
desc: shareDesc,
link: shareLink,
imgUrl: shareImg,
success: () => {}
})
})
wx.error((e: unknown) => {
console.error('[WxShare] wx.error:', e)
})
}
</script>
<template>
<div style="display: none" />
<!-- 该组件无可视内容仅用于初始化微信分享 -->
</template>

View File

@@ -98,6 +98,37 @@ const links = computed(() => {
return [...links, ...(appConfig.toc?.bottom?.links || [])].filter(Boolean)
})
// ===== 微信分享(测试按钮用)=====
const wxShareActive = ref(false)
// const contentRoot = ref<HTMLElement | null>(null)
const shareLink = 'https://lijue.me' + decodeURIComponent(path.value)
const shareTitle = computed(() => title)
const shareDesc = computed(() => description || title)
const shareImg = page?.value?.img
// const shareImg = ref<string>('/images/default-blog.jpg')
// onMounted(() => {
// // 从正文中抓取第一张图片作为分享图
// const el = contentRoot.value
// const firstImg = el?.querySelector('img') as HTMLImageElement | null
// if (firstImg?.src) {
// shareImg.value = firstImg.src
// }
// })
// Toast点击测试分享后给出指引
const toast = useToast()
function handleShareClick() {
wxShareActive.value = true
toast.add({
title: '已获取分享接口',
description: '点击右上角分享吧',
duration: 3000,
icon: 'i-lucide-share-2'
})
}
</script>
<template>
@@ -147,7 +178,7 @@ const links = computed(() => {
编辑页面
</UButton>
or
<UButton
<!-- <UButton
variant="link"
color="neutral"
:to="`${appConfig.github.url}/issues/new/choose`"
@@ -156,10 +187,29 @@ const links = computed(() => {
:ui="{ leadingIcon: 'size-4' }"
>
提交问题
</UButton> -->
<UButton
variant="link"
color="neutral"
icon="lucide-share-2"
:ui="{ leadingIcon: 'size-4' }"
@click="handleShareClick()"
>
微信分享
</UButton>
</div>
</USeparator>
<UContentSurround :surround="surround" />
<!-- 激活后挂载分享组件无可视内容 -->
<SharedWxShare
v-if="wxShareActive"
:url="shareLink"
:title="shareTitle"
:desc="shareDesc"
:img-url="shareImg"
/>
</UPageBody>
<template