Files
estel_docs/app/components/shared/wxShare.vue
estel 046b0ef674
Some checks failed
CI / lint (push) Has been cancelled
CI / typecheck (push) Has been cancelled
CI / build (ubuntu-latest) (push) Has been cancelled
增加监听URL变化
2025-08-09 13:37:57 +08:00

109 lines
3.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import { onMounted, watch } 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)
}
})
// 路径变化时,重新获取签名并刷新分享数据(适配 SPA 场景)
watch(() => props.url, async (newUrl, oldUrl) => {
if (!newUrl || newUrl === oldUrl) return
try {
await loadWxSdk()
const { appId, timestamp, nonceStr, signature } = await getWxConfig()
setupShare(appId, timestamp, nonceStr, signature)
} catch (err) {
console.error('[WxShare] reconfig 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>