Skip to content

useShare 分享功能

介绍

useShare 是小程序分享功能组合函数,采用页面级单例模式实现。支持微信小程序、支付宝小程序等多平台的分享功能,同一页面内共享分享状态,不同页面间隔离状态。

核心特性:

  • 多平台支持 - 支持微信、支付宝、百度、QQ小程序等多平台
  • 页面级单例 - 同一页面内多个组件共享同一个分享实例
  • 动态配置 - 支持动态设置分享标题、图片、路径等
  • 朋友圈分享 - 支持配置是否允许分享到朋友圈
  • 自动参数 - 自动携带用户ID等参数,支持分销追踪

基本用法

基础使用

在页面中使用 useShare 启用分享功能:

vue
<script lang="ts" setup>
import { useShare } from '@/composables/useShare'

// 使用默认配置
const { handleShareAppMessage, handleShareTimeline } = useShare()

// 暴露分享方法给页面
defineExpose({
  onShareAppMessage: handleShareAppMessage,
  onShareTimeline: handleShareTimeline,
})
</script>

自定义分享配置

通过传入配置对象自定义分享内容:

vue
<script lang="ts" setup>
import { useShare } from '@/composables/useShare'

const { handleShareAppMessage, handleShareTimeline } = useShare({
  title: '精彩内容等你发现',
  imageUrl: '/static/share-cover.png',
  enableTimeline: true, // 允许分享到朋友圈
})

defineExpose({
  onShareAppMessage: handleShareAppMessage,
  onShareTimeline: handleShareTimeline,
})
</script>

动态设置分享数据

根据接口返回的数据动态设置分享内容:

vue
<script lang="ts" setup>
import { useShare } from '@/composables/useShare'
import { onMounted } from 'vue'

const { setShareData, handleShareAppMessage, handleShareTimeline } = useShare()

onMounted(async () => {
  // 获取商品详情
  const product = await fetchProductDetail(productId)

  // 动态设置分享数据
  setShareData({
    title: product.name,
    imageUrl: product.coverImage,
    extraParams: {
      productId: product.id,
      source: 'share'
    }
  })
})

defineExpose({
  onShareAppMessage: handleShareAppMessage,
  onShareTimeline: handleShareTimeline,
})
</script>

主动触发分享

通过按钮点击主动触发系统分享菜单:

vue
<template>
  <wd-button @click="onShareClick">分享给好友</wd-button>
</template>

<script lang="ts" setup>
import { useShare } from '@/composables/useShare'

const { triggerShare } = useShare()

const onShareClick = () => {
  triggerShare()
}
</script>

检查朋友圈分享权限

判断当前页面是否允许分享到朋友圈:

vue
<script lang="ts" setup>
import { useShare } from '@/composables/useShare'

const { canShareToTimeline } = useShare()

// 检查是否可以分享到朋友圈
if (canShareToTimeline()) {
  console.log('当前页面允许分享到朋友圈')
} else {
  console.log('当前页面不允许分享到朋友圈')
}
</script>

重置分享配置

将分享配置重置为默认值:

vue
<script lang="ts" setup>
import { useShare } from '@/composables/useShare'

const { resetShareConfig } = useShare()

// 在某些场景下重置分享配置
const handleReset = () => {
  resetShareConfig()
}
</script>

分享配置

页面分享配置

可以在组件内部的 PAGE_SHARE_CONFIG 中预设各页面的分享配置:

typescript
const PAGE_SHARE_CONFIG: Record<string, PageShareConfig> = {
  // 首页配置
  '/pages/index/index': {
    title: '首页',
    imageUrl: '',
    enableTimeline: true,
  },
  // 产品详情页配置
  '/pages/product/detail': {
    title: '产品详情',
    imageUrl: '',
    enableTimeline: true,
  },
  // 用户中心 - 私密页面,不允许分享到朋友圈
  '/pages/user/profile': {
    title: '个人中心',
    imageUrl: '',
    enableTimeline: false,
  },
}

默认分享配置

当页面没有自定义配置时使用默认配置:

typescript
const DEFAULT_SHARE: ShareConfig = {
  title: '发现更多精彩',
  path: '/pages/index/index',
  imageUrl: '',
}

API

useShare 参数

参数说明类型默认值
customConfig自定义页面分享配置PageShareConfig-

useShare 返回值

属性/方法说明类型
shareConfig当前分享配置(只读)Readonly<Ref<ShareConfig>>
pageConfig页面配置(只读)Readonly<Ref<PageShareConfig>>
setShareData动态设置分享数据(data: ShareData) => void
triggerShare主动触发分享菜单() => void
resetShareConfig重置分享配置() => void
canShareToTimeline检查是否支持朋友圈分享() => boolean
handleShareAppMessage处理分享到好友() => ShareEventResult
handleShareTimeline处理分享到朋友圈() => ShareEventResult | null

类型定义

typescript
/**
 * 分享配置接口
 */
interface ShareConfig {
  /** 分享标题 */
  title: string
  /** 分享路径,包含参数 */
  path: string
  /** 分享图片地址 */
  imageUrl: string
}

/**
 * 页面分享配置接口
 */
interface PageShareConfig {
  /** 页面分享标题 */
  title?: string
  /** 页面分享图片 */
  imageUrl?: string
  /** 是否允许分享到朋友圈 */
  enableTimeline?: boolean
}

/**
 * 动态设置分享数据的接口
 */
interface ShareData {
  /** 动态标题 */
  title?: string
  /** 动态图片 */
  imageUrl?: string
  /** 额外的路径参数 */
  extraParams?: Record<string, any>
  /** 是否覆盖现有路径 */
  overridePath?: boolean
}

/**
 * 分享事件回调参数
 */
interface ShareEventResult {
  title: string
  path: string
  imageUrl?: string
}

平台适配

微信小程序

typescript
// 微信小程序分享菜单配置
uni.showShareMenu({
  withShareTicket: true,
  menus: ['shareAppMessage', 'shareTimeline']
})

支付宝小程序

typescript
// 支付宝小程序分享面板
my.showSharePanel({
  title: shareConfig.value.title,
  content: shareConfig.value.title,
  url: shareConfig.value.path,
})

百度小程序

typescript
// 百度小程序分享
swan.openShare({
  title: shareConfig.value.title,
  content: shareConfig.value.title,
  imageUrl: shareConfig.value.imageUrl,
  path: shareConfig.value.path,
})

QQ小程序

typescript
// QQ小程序分享菜单
qq.showShareMenu({
  showShareItems: ['qq', 'qzone', 'wechatFriends', 'wechatMoment'],
})

最佳实践

1. 商品分享带参数

vue
<script lang="ts" setup>
import { useShare } from '@/composables/useShare'
import { onLoad } from '@dcloudio/uni-app'

const { setShareData, handleShareAppMessage, handleShareTimeline } = useShare()

onLoad(async (options) => {
  const productId = options?.id
  if (productId) {
    const product = await getProductDetail(productId)

    setShareData({
      title: `【推荐】${product.name}`,
      imageUrl: product.mainImage,
      extraParams: {
        id: productId,
        inviteCode: 'ABC123'
      }
    })
  }
})

defineExpose({
  onShareAppMessage: handleShareAppMessage,
  onShareTimeline: handleShareTimeline,
})
</script>

2. 文章分享

vue
<script lang="ts" setup>
import { useShare } from '@/composables/useShare'

const { setShareData } = useShare({
  enableTimeline: true
})

// 文章加载完成后设置分享
const onArticleLoaded = (article: Article) => {
  setShareData({
    title: article.title,
    imageUrl: article.cover || '/static/default-article.png',
    extraParams: {
      articleId: article.id
    }
  })
}
</script>

3. 私密页面禁止朋友圈分享

vue
<script lang="ts" setup>
import { useShare } from '@/composables/useShare'

// 订单详情页 - 禁止分享到朋友圈
const { handleShareAppMessage, handleShareTimeline } = useShare({
  title: '订单详情',
  enableTimeline: false
})

defineExpose({
  onShareAppMessage: handleShareAppMessage,
  onShareTimeline: handleShareTimeline,
})
</script>

常见问题

1. 分享参数丢失?

确保在 setShareData 中正确设置了 extraParams

typescript
setShareData({
  title: '分享标题',
  extraParams: {
    id: '123',
    source: 'share'
  }
})

2. 朋友圈分享不显示?

检查 enableTimeline 是否设置为 true,以及页面配置中是否允许朋友圈分享。

3. 多个组件共享状态?

useShare 采用页面级单例模式,同一页面内多次调用返回相同实例,共享分享状态。

4. 自动携带用户ID?

分享时会自动在参数中添加 pid(用户ID),用于分销追踪:

typescript
// 自动构建分享参数
const buildShareParams = (baseParams, extraParams, overridePath) => {
  const userId = userStore.userInfo?.userId
  return {
    ...finalBaseParams,
    ...extraParams,
    ...(userId && { pid: userId })
  }
}