添加微信分享功能
This commit is contained in:
@@ -9,7 +9,7 @@ export default defineAppConfig({
|
||||
}
|
||||
},
|
||||
seo: {
|
||||
siteName: 'Nuxt Docs Template'
|
||||
siteName: 'Estel Docs'
|
||||
},
|
||||
header: {
|
||||
title: 'Estel Docs',
|
||||
|
@@ -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>
|
||||
|
96
app/components/shared/wxShare.vue
Normal file
96
app/components/shared/wxShare.vue
Normal 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>
|
@@ -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
|
||||
|
Reference in New Issue
Block a user