# Nuxt3 社群分享功能 如何在 Nuxt3 中使用官方提供的 Web API 實作社群媒體分享功能。 --- ## 功能特色 ✅ 支援多個社群平台: - Facebook - WhatsApp - LINE (桌面版/行動版) - Email - X (Twitter) - 微博 (Weibo) ✅ 無需第三方套件 ✅ 使用官方分享 API ✅ 支援 RWD (LINE 自動判斷裝置) --- ## 完整實作 ### Template ```vue <template> <div class="share-container"> <h3>分享到</h3> <ul class="share-list"> <!-- Facebook --> <li> <a :href="shareFB" target="_blank" rel="noopener noreferrer"> <img src="@/assets/img/icon_fb_logo.svg" alt="分享到 Facebook"> </a> </li> <!-- WhatsApp --> <li> <a :href="shareWhatsapp" target="_blank" rel="noopener noreferrer"> <img src="@/assets/img/icon_whatsapp_logo.svg" alt="分享到 WhatsApp"> </a> </li> <!-- LINE --> <li> <button @click="shareLine" type="button"> <img src="@/assets/img/icon_line_logo.svg" alt="分享到 LINE"> </button> </li> <!-- X (Twitter) --> <li> <a :href="shareX" target="_blank" rel="noopener noreferrer"> <img src="@/assets/img/icon_x_logo.svg" alt="分享到 X"> </a> </li> <!-- 微博 --> <li> <a :href="shareWeibo" target="_blank" rel="noopener noreferrer"> <img src="@/assets/img/icon_weibo_logo.svg" alt="分享到微博"> </a> </li> <!-- Email --> <li> <a :href="shareEmail"> <img src="@/assets/img/icon_email.svg" alt="Email 分享"> </a> </li> </ul> </div> </template> ``` --- ### Script Setup ```vue <script setup> // =========================== // 分享設定 // =========================== // 分享文字內容 const shareText = '來看看這個精彩內容!' const shareTitle = '文章標題' // 分享連結 const shareFB = ref('') const shareWhatsapp = ref('') const shareLine = ref('') const shareX = ref('') const shareWeibo = ref('') const shareEmail = ref('') /** * 取得當前頁面網址 * @returns {string} 當前完整 URL */ const getCurrentUrl = () => { if (process.client) { return window.location.href } return '' } /** * LINE 分享 * 桌面版: 開啟 LINE 分享視窗 * 行動版: 開啟 LINE App */ const handleShareLine = () => { if (!process.client) return const url = encodeURIComponent(getCurrentUrl()) // 判斷是否為桌面版 (寬度 > 960px) if (window.innerWidth > 960) { // 桌面版: 開啟 LINE 社群外掛 window.open(`https://social-plugins.line.me/lineit/share?url=${url}`) } else { // 行動版: 開啟 LINE App const message = encodeURIComponent(`${shareText}\n${getCurrentUrl()}`) window.location.href = `line://msg/text/${message}` } } /** * 初始化所有分享連結 */ const initializeShareLinks = () => { if (!process.client) return const currentUrl = getCurrentUrl() const encodedUrl = encodeURIComponent(currentUrl) const encodedText = encodeURIComponent(shareText) const encodedTitle = encodeURIComponent(shareTitle) // Facebook 分享 shareFB.value = `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}` // WhatsApp 分享 shareWhatsapp.value = `https://api.whatsapp.com/send?text=${encodedText}:${encodedUrl}` // X (Twitter) 分享 shareX.value = `https://twitter.com/intent/tweet?text=${encodedText}&url=${encodedUrl}` // 微博分享 shareWeibo.value = `http://service.weibo.com/share/share.php?url=${encodedUrl}&title=${encodedText}` // Email 分享 const emailSubject = encodeURIComponent('推薦給你') const emailBody = encodeURIComponent(`${shareText}\n${shareTitle}\n${currentUrl}`) shareEmail.value = `mailto:?subject=${emailSubject}&body=${emailBody}` } // 頁面載入時初始化分享連結 onMounted(() => { initializeShareLinks() }) </script> ``` --- ### Style (SCSS) ```vue <style lang="scss" scoped> .share-container { padding: 1.5rem; h3 { margin-bottom: 1rem; font-size: 1.125rem; font-weight: 600; } } .share-list { display: flex; gap: 1rem; list-style: none; padding: 0; margin: 0; flex-wrap: wrap; li { a, button { display: inline-flex; align-items: center; justify-content: center; width: 48px; height: 48px; padding: 0; background: transparent; border: none; cursor: pointer; transition: transform 0.2s ease; &:hover { transform: scale(1.1); } &:active { transform: scale(0.95); } img { width: 100%; height: 100%; object-fit: contain; } } } } // 響應式設計 @media (max-width: 768px) { .share-list { gap: 0.75rem; li a, li button { width: 40px; height: 40px; } } } </style> ``` --- ## 各平台分享 API 說明 ### 1. Facebook ```javascript // 基本格式 https://www.facebook.com/sharer/sharer.php?u={URL} // 範例 shareFB.value = `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}` ``` **注意事項:** - ⚠️ 在 localhost 無法正常運作 (Facebook 審核機制) - 需要在測試機或正式機測試 - 分享的標題、圖片、描述由 Open Graph 標籤決定 - 如果顯示舊內容,請使用 [Facebook 分享偵錯工具](https://developers.facebook.com/tools/debug/)清除快取 --- ### 2. WhatsApp ```javascript // 基本格式 https://api.whatsapp.com/send?text={文字} // 範例 const text = encodeURIComponent('來看看這個!') const url = encodeURIComponent(window.location.href) shareWhatsapp.value = `https://api.whatsapp.com/send?text=${text}:${url}` ``` **特性:** - 桌面版和行動版使用相同 URL - 會自動開啟 WhatsApp 網頁版或 App --- ### 3. LINE LINE 需要根據裝置類型使用不同的 URL: ```javascript const shareLine = () => { if (!process.client) return const url = getCurrentUrl() if (window.innerWidth > 960) { // 桌面版: LINE 社群外掛 window.open(`https://social-plugins.line.me/lineit/share?url=${encodeURIComponent(url)}`) } else { // 行動版: LINE App URL Scheme const message = encodeURIComponent(`${text}\n${url}`) window.location.href = `line://msg/text/${message}` } } ``` **URL Scheme 說明:** - 桌面版: `https://social-plugins.line.me/lineit/share?url={URL}` - 行動版: `line://msg/text/{訊息}` --- ### 4. X (Twitter) ```javascript // 基本格式 https://twitter.com/intent/tweet?text={文字}&url={URL} // 範例 const text = encodeURIComponent('來看看這個!') const url = encodeURIComponent(window.location.href) shareX.value = `https://twitter.com/intent/tweet?text=${text}&url=${url}` ``` **可用參數:** - `text`: 推文內容 - `url`: 分享網址 - `hashtags`: 標籤 (逗號分隔) - `via`: 提及的使用者 --- ### 5. 微博 (Weibo) ```javascript // 基本格式 http://service.weibo.com/share/share.php?url={URL}&title={標題} // 範例 const url = encodeURIComponent(window.location.href) const title = encodeURIComponent('文章標題') shareWeibo.value = `http://service.weibo.com/share/share.php?url=${url}&title=${title}` ``` --- ### 6. Email ```javascript // 基本格式 mailto:?subject={主旨}&body={內容} // 範例 const subject = encodeURIComponent('推薦給你') const body = encodeURIComponent(`來看這篇文章\n${url}`) shareEmail.value = `mailto:?subject=${subject}&body=${body}` ``` **注意:** - 換行使用 `\n` - 需要 URL encode - 會開啟使用者預設的郵件客戶端 --- ## 進階功能 ### 1. 使用 Composable 封裝 建立 `composables/useSocialShare.js`: ```javascript export const useSocialShare = () => { /** * 取得當前頁面 URL */ const getCurrentUrl = () => { if (!process.client) return '' return window.location.href } /** * 產生 Facebook 分享連結 */ const getFacebookShareUrl = (url = getCurrentUrl()) => { return `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}` } /** * 產生 WhatsApp 分享連結 */ const getWhatsAppShareUrl = (text, url = getCurrentUrl()) => { const encodedText = encodeURIComponent(text) const encodedUrl = encodeURIComponent(url) return `https://api.whatsapp.com/send?text=${encodedText}:${encodedUrl}` } /** * 產生 X (Twitter) 分享連結 */ const getXShareUrl = (text, url = getCurrentUrl(), hashtags = '') => { const encodedText = encodeURIComponent(text) const encodedUrl = encodeURIComponent(url) let shareUrl = `https://twitter.com/intent/tweet?text=${encodedText}&url=${encodedUrl}` if (hashtags) { shareUrl += `&hashtags=${encodeURIComponent(hashtags)}` } return shareUrl } /** * 產生微博分享連結 */ const getWeiboShareUrl = (title, url = getCurrentUrl()) => { const encodedTitle = encodeURIComponent(title) const encodedUrl = encodeURIComponent(url) return `http://service.weibo.com/share/share.php?url=${encodedUrl}&title=${encodedTitle}` } /** * 產生 Email 分享連結 */ const getEmailShareUrl = (subject, body) => { const encodedSubject = encodeURIComponent(subject) const encodedBody = encodeURIComponent(body) return `mailto:?subject=${encodedSubject}&body=${encodedBody}` } /** * LINE 分享 */ const shareLine = (text, url = getCurrentUrl()) => { if (!process.client) return const encodedUrl = encodeURIComponent(url) if (window.innerWidth > 960) { // 桌面版 window.open(`https://social-plugins.line.me/lineit/share?url=${encodedUrl}`) } else { // 行動版 const message = encodeURIComponent(`${text}\n${url}`) window.location.href = `line://msg/text/${message}` } } return { getCurrentUrl, getFacebookShareUrl, getWhatsAppShareUrl, getXShareUrl, getWeiboShareUrl, getEmailShareUrl, shareLine } } ``` **使用範例:** ```vue <script setup> const { getFacebookShareUrl, getWhatsAppShareUrl, shareLine } = useSocialShare() const shareText = '來看看這個精彩內容!' const shareFB = computed(() => getFacebookShareUrl()) const shareWhatsapp = computed(() => getWhatsAppShareUrl(shareText)) </script> ``` --- ### 2. 支援動態內容分享 ```vue <script setup> // 假設從 API 取得文章資料 const { data: article } = await useFetch('/api/article/123') // 動態產生分享內容 const shareText = computed(() => { return article.value?.title || '精彩內容' }) const shareUrl = computed(() => { if (!process.client) return '' return window.location.href }) // 使用動態內容 const shareFB = computed(() => { return `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(shareUrl.value)}` }) const shareWhatsapp = computed(() => { const text = encodeURIComponent(shareText.value) const url = encodeURIComponent(shareUrl.value) return `https://api.whatsapp.com/send?text=${text}:${url}` }) </script> ``` --- ### 3. 加入分享追蹤 (UTM 參數) ```javascript const getShareUrlWithTracking = (baseUrl, platform) => { const url = new URL(baseUrl) url.searchParams.set('utm_source', platform) url.searchParams.set('utm_medium', 'social') url.searchParams.set('utm_campaign', 'share') return url.toString() } // 使用範例 const currentUrl = getCurrentUrl() const facebookUrl = getShareUrlWithTracking(currentUrl, 'facebook') shareFB.value = `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(facebookUrl)}` ``` --- ### 4. Web Share API (原生分享) 現代瀏覽器支援原生分享功能: ```vue <script setup> const canShare = ref(false) onMounted(() => { // 檢查是否支援 Web Share API canShare.value = process.client && navigator.share !== undefined }) const handleNativeShare = async () => { if (!canShare.value) return try { await navigator.share({ title: '文章標題', text: '來看看這個精彩內容!', url: window.location.href }) console.log('分享成功') } catch (error) { if (error.name !== 'AbortError') { console.error('分享失敗:', error) } } } </script> <template> <!-- 顯示原生分享按鈕 --> <button v-if="canShare" @click="handleNativeShare"> <img src="@/assets/img/icon_share.svg" alt="分享"> </button> <!-- 其他平台分享按鈕 --> <ul v-else class="share-list"> <!-- ... --> </ul> </template> ``` **Web Share API 特性:** - ✅ 自動顯示裝置上可用的分享選項 - ✅ 更好的使用者體驗 - ⚠️ 僅在 HTTPS 環境下可用 - ⚠️ 必須由使用者互動觸發 (如按鈕點擊) --- ## 常見問題 ### Q: Facebook 分享在本地環境無法運作? A: Facebook 不允許分享 localhost 的網址,需要部署到測試機或正式機才能測試。 --- ### Q: Facebook 分享顯示的標題/圖片不正確? A: 1. 確認網頁有正確設定 Open Graph 標籤 2. 使用 [Facebook 分享偵錯工具](https://developers.facebook.com/tools/debug/)清除快取 3. 強制重新抓取內容 ```html <!-- 必要的 OG 標籤 --> <meta property="og:title" content="頁面標題"> <meta property="og:description" content="頁面描述"> <meta property="og:image" content="https://example.com/image.jpg"> <meta property="og:url" content="https://example.com/page"> ``` --- ### Q: LINE 分享在桌面版無法開啟? A: 確認使用正確的 URL: - 桌面版: `https://social-plugins.line.me/lineit/share?url={URL}` - 行動版: `line://msg/text/{訊息}` --- ### Q: 如何判斷使用者使用的裝置? A: 可以使用 `window.innerWidth` 或 User Agent: ```javascript // 方法一: 螢幕寬度 const isMobile = window.innerWidth <= 960 // 方法二: User Agent const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent ) ``` --- ### Q: 分享連結中的特殊字元如何處理? A: 使用 `encodeURIComponent()` 編碼: ```javascript const url = 'https://example.com/article?id=123&lang=zh' const encodedUrl = encodeURIComponent(url) // 輸出: https%3A%2F%2Fexample.com%2Farticle%3Fid%3D123%26lang%3Dzh ``` --- ## 瀏覽器相容性 | 功能 | Chrome | Firefox | Safari | Edge | |------|--------|---------|--------|------| | 基本分享連結 | ✅ | ✅ | ✅ | ✅ | | Web Share API | ✅ 89+ | ✅ 71+ | ✅ 12.2+ | ✅ 93+ | | LINE URL Scheme | ✅ | ✅ | ✅ | ✅ | --- ## 參考資源 - [Facebook 分享偵錯工具](https://developers.facebook.com/tools/debug/) - [Open Graph Protocol](https://ogp.me/) - [Web Share API - MDN](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/share) - [LINE Developers](https://developers.line.biz/) - [Twitter Web Intent](https://developer.twitter.com/en/docs/twitter-for-websites/tweet-button/overview)