最全的uniapp微信小程序分享功能(列表多个分享按钮,每个按钮都可设置不同参数,实现动态分享)

3,367 阅读4分钟

摘要

本文介绍了如何在uniapp微信小程序(uni-app3.0 + vue3.0)中使用微信分享功能,包括基本使用全局mixins混入动态设置参数(列表多个按钮场景)以及一些注意事项。

基本使用

首先在uniapp官网找到onShareAppMessage方法,根据介绍了解到 onShareAppMessage 方法和 onLoad 等生命周期函数同级,此方法需要 return 一个Object,用于自定义分享内容。

home.vue

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

onShareAppMessage(() => {
  return {
    title: '这是分享标题',
    path: '/pages/home/home',
  }
})
</script>

上述示例代码就是一个最基础的页面分享配置,此时会发现点击小程序右上角的胶囊按钮,转发给朋友分享到朋友圈已经处于激活状态了。

这里有个问题:分享到朋友圈按照文档应该是要配置onShareTimeline方法才对,但是当把 onShareTimeline 引入之后就会报错(暂时不清楚原因,知道的jym可以评论区说下

要配置 onShareTimeline 可以使用以下方式:

home.vue

<script lang="ts">
export default {
  // 分享朋友圈onShareTimeline不支持自定义路径path
  onShareTimeline() {
    return {
      title: '这是分享朋友圈标题'
    }
  }
}
</script>

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

onShareAppMessage(() => {
  return {
    title: '这是分享标题',
    path: '/pages/home/home',
  }
})
</script>

全局mixins混入

如果产品要求小程序的每个页面都要有分享功能,一个个页面去配置的话就会很费时间,而且产生代码冗余,下面介绍通过mixins混入的方式配置页面分享功能

wxMiniShare.ts

export default {
  data() {
    return {
      miniShareOptions: {
        // 分享标题
        title: 'IP数字化运营平台',
        // 页面 path,不建议直接配置分享哪个页面就配置哪个页面的路径,有些页面不建议分享,如订单页,所以默认都是分享首页
        path: '/pages/home/home',
        // 分享图标,路径可以是本地文件路径、代码包文件路径或者网络图片路径。支持PNG及JPG。显示图片长宽比是 5:4
        imageUrl: ''
      },
      shareCover: '这里可以放分享的封面图'
    }
  },
  // 发送给朋友
  onShareAppMessage() {
    return {
      ...this.miniShareOptions,
      imageUrl: this.shareCover
    }
  }
}
main.ts

import { createSSRApp } from 'vue'
import App from './App.vue'
import wxMiniShare from '@/mixins/wxMiniShare'

export function createApp() {
  const app = createSSRApp(App)

  app.mixin(wxMiniShare) // 全局混入微信分享

  return {
    app
  }
}

上述配置完之后,小程序的每个页面上转发给朋友的按钮就都激活了,这时候已经满足每个页面有分享按钮的需求了,但是有些页面如文章详情页,需要根据不同文章做不同的分享配置。

details.vue

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

const recordId = ref('')
const recordInfo = ref({})

onLoad((e) => {
  recordId.value = e?.id
  getWorkInfo()
})

const getWorkInfo = async() => {
  const res = await recordProdDetailApi(recordId.value)
  if (res.code == 200) {
    recordInfo.value = res.data
  }
}
</script>

首先尝试写在script标签,但是无法获取到 recordInfo 的值

details.vue

<script lang="ts">
export default {
  // 实际上无法获取到recordInfo的值
  onShareAppMessage() {
    return {
      title: recordInfo.value.prodName,
      path: `/pages/home/details?id=${recordInfo.value.id}`,
      imageUrl: recordInfo.value.cover
    }
  }
}
</script>

<script setup lang="ts">
...
</script>

然后尝试写在setup里,但是无法覆盖mixins混入的方法

details.vue

import { onLoad, onShareAppMessage } from '@dcloudio/uni-app'

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

const recordId = ref('')
const recordInfo = ref({})

onLoad((e) => {
  recordId.value = e?.id
  getWorkInfo()
})

// 实际上这里无法覆盖混入的onShareAppMessage方法
onShareAppMessage(() => {
  return {
    title: recordInfo.value.prodName,
    path: `/pages/home/details?id=${recordInfo.value.id}`,
    imageUrl: recordInfo.value.cover
  }
})

const getWorkInfo = async() => {
  const res = await recordProdDetailApi(recordId.value)
  if (res.code == 200) {
    recordInfo.value = res.data
  }
}
</script>

最后在dcloud社区上找了一种解决方案——把 onShareAppMessage 写到 onLoad / onMounted 里面即可解决

details.vue

import { onLoad, onShareAppMessage } from '@dcloudio/uni-app'

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

const recordId = ref('')
const recordInfo = ref({})

onLoad((e) => {
  recordId.value = e?.id
  getWorkInfo()

  onShareAppMessage(() => {
    return {
      title: recordInfo.value.prodName,
      path: `/pages/community/workDetail?id=${recordInfo.value.id}`,
      imageUrl: recordInfo.value.cover
    }
  })
})

const getWorkInfo = async() => {
  const res = await recordProdDetailApi(recordId.value)
  if (res.code == 200) {
    recordInfo.value = res.data
  }
}
</script>

动态设置参数(列表多个按钮场景)

以上都是针对页面右上角胶囊按钮去固定分享,在需求中也会遇到需要动态配置分享参数的场景,比如列表有多篇文章,每篇文章都有一个按钮可以分享,这种就需要使用<button open-type="share">去唤起操作栏。

分享.png

实现思路就是用data-share动态的给每个按钮配置不同的参数:

community.vue

<template>
    <view v-for="(item, index) in listData" :key="index">
      <button
        open-type="share"
        :data-share="{
          title: item.prodName,
          path: `/pages/community/workDetail?id=${item.id}`
        }"
        class="work-share flex_row_center"
      >
        <image src="/static/images/icon/icon-share.png" />分享好友
      </button>
    </view>
</template>

<script lang="ts">
export default {
  onShareAppMessage(e) {
    if (e.from === 'button') {
      let { title, path } = e.target.dataset.share
      return {
        ...this.miniShareOptions,
        imageUrl: this.shareCover,
        title,
        path
      }
    }
    return {
      ...this.miniShareOptions,
      imageUrl: this.shareCover,
      path: '/pages/community/community'
    }
  }
}
</script>

onShareAppMessage和onShareTimeline有两个重要的参数fromtarget

  • from 分享事件来源:button(页面内分享按钮)、menu(右上角分享按钮)
  • target 如果 from 值是 button,则 target 是触发这次分享事件的 button,否则为 undefined

参数.png

注意&总结

单个页面配置和全局混入各有优劣,看情况取舍

  • 单页面配置:缺点:费时、产生代码冗余,只配置转发给朋友也会强制激活分享到朋友圈;优点:可灵活配置
  • 全局混入:缺点:一旦混入,想要取消某个页面的分享就没法取消了(折中做法就是只混入转发给朋友功能,并且path指向到首页);优点:省时、代码简洁

分享到朋友圈不支持自定义路径

分享朋友圈onShareTimeline不支持自定义路径,因此只能在需要分享的页面去单独配置(需要用户登录的页面不配置)