index.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <template>
  2. <!-- 分享弹窗 -->
  3. <uni-popup ref="popupRef" type="bottom" background-color="#fff" :mask-click="false">
  4. <view class="share-popup-container">
  5. <!-- 标题 -->
  6. <view class="share-header">
  7. <text class="share-title">分享到</text>
  8. </view>
  9. <!-- 分享选项 -->
  10. <scroll-view scroll-x class="share-scroll" :show-scrollbar="false">
  11. <view class="share-list">
  12. <!-- 微信好友 -->
  13. <view class="share-item" @click="select('session')">
  14. <view class="share-icon wechat-icon"></view>
  15. <text class="share-text">微信好友</text>
  16. </view>
  17. <!-- 朋友圈 -->
  18. <view class="share-item" @click="select('timeline')">
  19. <view class="share-icon timeline-icon"></view>
  20. <text class="share-text">朋友圈</text>
  21. </view>
  22. </view>
  23. <view class="share-close" @click="close">取消</view>
  24. </scroll-view>
  25. </view>
  26. </uni-popup>
  27. </template>
  28. <script setup>
  29. import {
  30. ref
  31. } from 'vue'
  32. // 定义props
  33. const props = defineProps({
  34. // 分享标题
  35. title: {
  36. type: String,
  37. default: '分享标题'
  38. },
  39. // type=0: 图文分享(需要 title + summary + imageUrl)
  40. // type=1: 纯图片分享(只需要 imageUrl)
  41. // type=2: 链接分享(需要 title + summary + href + imageUrl)
  42. type: {
  43. type: String,
  44. default: "0" // 0:图文
  45. },
  46. // 分享描述
  47. desc: {
  48. type: String,
  49. default: '分享描述'
  50. },
  51. // 分享链接
  52. link: {
  53. type: String,
  54. default: ''
  55. },
  56. // 分享图片
  57. image: {
  58. type: String,
  59. default: ''
  60. },
  61. })
  62. const emit = defineEmits(['close', 'select', 'success', 'error'])
  63. const popupRef = ref(null)
  64. // 打开弹窗
  65. const open = () => {
  66. popupRef.value.open()
  67. }
  68. // 关闭弹窗
  69. const close = () => {
  70. popupRef.value.close()
  71. emit('close')
  72. }
  73. // 选择分享方式
  74. const select = (scene) => {
  75. //emit('select', scene)
  76. try {
  77. shareToWeChat(scene)
  78. close()
  79. } catch (error) {
  80. emit('error', error)
  81. handleShareError(error)
  82. }
  83. }
  84. // 分享到微信
  85. const shareToWeChat = (scene) => {
  86. console.log('props.link',props.link);
  87. uni.share({
  88. provider: 'weixin',
  89. scene: scene === 'timeline' ? 'WXSceneTimeline' : 'WXSceneSession',
  90. type: Number(props.type),
  91. title: props.title,
  92. summary: props.desc,
  93. href: props.link,
  94. imageUrl: props.image || 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni@2x.png',
  95. success: function(res) {
  96. emit('success', {
  97. scene
  98. })
  99. },
  100. fail: function(err) {
  101. emit('error', err)
  102. handleShareError(err)
  103. }
  104. })
  105. }
  106. // 错误处理
  107. const handleShareError = (error) => {
  108. console.error('分享失败:', error)
  109. const errCode = error.errCode || error.code
  110. const errMsg = error.errMsg || error.message
  111. // 微信未安装
  112. if (errCode === 1004 || errCode === -4004) {
  113. uni.showModal({
  114. title: '提示',
  115. content: '请先安装微信',
  116. showCancel: false
  117. })
  118. return
  119. }
  120. // 用户取消不提示
  121. if (errCode === 1001 || errCode === -4001) {
  122. return
  123. }
  124. // 其他错误
  125. uni.showToast({
  126. title: errMsg || '分享失败,请重试',
  127. icon: 'none',
  128. duration: 3000
  129. })
  130. }
  131. // 暴露方法给父组件
  132. defineExpose({
  133. open,
  134. close
  135. })
  136. </script>