uniapp項(xiàng)目實(shí)踐自定義分享組件示例
準(zhǔn)備工作
這篇文章主要是講述自定義分享組件的方放,兼容網(wǎng)頁 H5 端、微信小程序端和 App 端。
- 首先我們從圖標(biāo)圖庫網(wǎng)站上面找一些常用的分享圖標(biāo)并下載下來;
- 在
components
新建一個(gè)q-share
文件夾,并新建一個(gè)q-share.vue
的組件; - 按照前一篇所說的頁面結(jié)構(gòu),編寫好預(yù)定的分享頁面;
原理分析
自定義分享組件就是采用各端支持的 API 方法進(jìn)行封裝設(shè)置,利用條件編譯的語法進(jìn)行分而實(shí)現(xiàn)。
H5 端分析
H5 端主要有兩種分享方法:
- 普通瀏覽器自帶分享按鈕;微信內(nèi)嵌瀏覽器,可調(diào)用js-sdk進(jìn)行分享;
- 第三方平臺(tái)網(wǎng)頁應(yīng)用:在第三方分享平臺(tái)申請(qǐng)?zhí)砑幼约旱膽?yīng)用,以便調(diào)用第三方的分享 API 進(jìn)行分享;
- 網(wǎng)上公共分享鏈接:這里就使用網(wǎng)上公開的分享地址進(jìn)行分享了。
以下羅列了幾個(gè)常用的第三方分享平臺(tái)的地址,感興趣的可以收藏看一下。
常用開放平臺(tái):
小程序端分析
小程序端的分享目前 uniapp 不支持 API 調(diào)用,只能用戶主動(dòng)點(diǎn)擊觸發(fā)分享,可使用自定義按鈕方式<button open-type="share">
或監(jiān)聽系統(tǒng)右上角的分享按鈕onShareAppMessage
進(jìn)行自定義分享內(nèi)容。
在這里可以查看微信小程序的分享 API進(jìn)行小程序分享功能開發(fā)。
小程序文檔:
APP 端分析
APP 端的分享可以自主控制分享的內(nèi)容、形式及平臺(tái),提供了以下兩種方法:
- 使用uni.shareAPI 方式調(diào)用社交 sdk 分享;
- 使用plus.share.sendWithSystem呼起手機(jī)系統(tǒng)的分享菜單;
開發(fā)者官網(wǎng):
快應(yīng)用官網(wǎng):
組件實(shí)現(xiàn)
準(zhǔn)備工作和原理分析完成后,接下來寫一個(gè)簡(jiǎn)單的自定義分享組件。
模板部分
<view class="q-share" v-if="shares.show"> <view :class="{'q-share-mak': true, 'active': shares.showMask}" @click="close('mask')"></view> <view :class="{'q-share-inner': true, [shares.options.dir]: true, 'active': shares.showBox}" :style="{'width': `${['left', 'right'].includes(shares.options.dir) ? shares.options.width + 'rpx' : '100%'}`, 'height': `${['up', 'down'].includes(shares.options.dir) ? shares.options.height + 'rpx' : '100%'}`, borderRadius: shares.options.radius+'rpx'}"> <slot name="box"> <view class="q-share-box"> <view class="q-share-title"> 系統(tǒng)分享 </view> <scroll-view :scroll-x="true" class="q-share-content"> <view class="q-share-list" :style="{'width': shareList.length*145+'rpx'}"> <view class="q-share-item" v-for="item in shareList" :key="item.id" @click="shareSet(item)"> <q-icon class="q-share-item-icon" :name="item.val" :size="20" /> <text class="q-share-item-txt">{{item.name}}</text> </view> </view> </scroll-view> <view class="q-share-cancel" @click="close('cancel')"> 取消分享 </view> </view> </slot> </view> </view>
樣式部分
.q-share { position: fixed; left: 0; top: 0; width: 100%; height: 100vh; z-index: 199; .q-share-mak { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.45); transition: background 2s; z-index: 90; &.active { background: rgba(0, 0, 0, 0.35); } } .q-share-inner { position: absolute; max-width: 100%; max-height: 100%; background: rgba(255, 255, 255, 0.95); transition: all 0.5s; z-index: 95; .q-share-box { display: flex; flex-direction: column; justify-content: center; align-items: center; box-sizing: border-box; padding: 15rpx 25rpx; width: 100%; height: 100%; .q-share-title { width: 100%; line-height: 3; font-size: 28rpx; color: $uni-text-color; text-align: center; } .q-share-content { flex: 1; box-sizing: border-box; padding: 20rpx; width: 100%; height: calc(100% - 140rpx); .q-share-list { display: flex; flex-flow: row nowrap; box-sizing: border-box; padding: 25rpx 0; height: 100%; .q-share-item { display: flex; justify-content: center; align-items: center; flex-direction: column; width: 145rpx; height: 100%; .q-share-item-icon { padding: 0; } .q-share-item-txt { margin-top: 10rpx; font-size: 24rpx; } } } } .q-share-cancel { width: 100%; line-height: 2; font-size: 28rpx; color: $uni-text-color-grey; text-align: center; } } &.down, &.up { left: 0; } &.down { bottom: 0; border-bottom-left-radius: 0 !important; border-bottom-right-radius: 0 !important; transform: translateY(100%); &.active { transform: translateY(0); } } &.up { top: 0; border-top-left-radius: 0 !important; border-top-right-radius: 0 !important; transform: translateY(-100%); &.active { transform: translateY(0); } } &.left, &.right { top: 0; width: 0; } &.left { left: 0; border-top-left-radius: 0 !important; border-bottom-left-radius: 0 !important; transform: translateX(-100%); &.active { transform: translateX(0); } } &.right { right: 0; border-top-right-radius: 0 !important; border-bottom-right-radius: 0 !important; transform: translateX(100%); &.active { transform: translateX(0); } } } }
腳本部分
- 引入依賴包和屬性設(shè)置
import { ref, reactive, computed } from "vue"; // 屬性 const showTimer = ref(null); // 顯示延遲 const showTime = ref(100); // 顯示延遲時(shí)間 const showCloseTimer = ref(null); // 顯示關(guān)閉延遲 const showCloseTime = ref(300); // 顯示關(guān)閉延遲時(shí)間 const shares = reactive({ show: false, // 顯示分享框 showMask: false, // 顯示模態(tài)框 showBox: false, // 顯示內(nèi)容動(dòng)畫 options: { // 父組件消息 dir: "down", // 內(nèi)容方向 radius: 0, // 圓角角度 width: 200, // 內(nèi)容寬度 height: 300, // 內(nèi)容高度 }, list: [ { id: 1, name: "QQ", val: "qq", url(url, title) { return `https://connect.qq.com/widget/shareqq/iframe_index.html?url=${url}&title=${title}`; }, }, { id: 2, name: "QQ空間", val: "qzone", url(url, title) { return `http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url=${url}&title=${title}&site=${url}`; }, }, { id: 3, name: "微博", val: "weibo", url(url, title) { return `http://service.weibo.com/share/share.php?url=${url}&title=${title}&language=zh_cn`; }, }, { id: 4, name: "微信", val: "wechat", url() { return ""; }, }, { id: 5, name: "百度", val: "baidu", url() { return ""; }, }, { id: 6, name: "貼吧", val: "tieba", url() { return ""; }, }, { id: 7, name: "朋友圈", val: "friend", url() { return ""; }, }, { id: 8, name: "淘寶", val: "taobao", url() { return ""; }, }, { id: 9, name: "支付寶", val: "alipay", url() { return ""; }, }, { id: 10, name: "釘釘", val: "dingtalk", url() { return ""; }, }, { id: 11, name: "快手", val: "gifks", url() { return ""; }, }, { id: 12, name: "Whatsapp", val: "whatsapp", url() { return ""; }, }, { id: 13, name: "Messenger", val: "messenger", url() { return ""; }, }, { id: 14, name: "Youtube", val: "youtube", url() { return ""; }, }, { id: 15, name: "Instagram", val: "instagram", url() { return ""; }, }, { id: 16, name: "Twitter", val: "twitter", url() { return ""; }, }, { id: 17, name: "Telegram", val: "telegram", url() { return ""; }, }, { id: 18, name: "復(fù)制鏈接", val: "link", url() { return location.href; }, }, { id: 19, name: "更多", val: "more", url() { return ""; }, }, ], info: { title: "", // 分享標(biāo)題 url: "", // 分享地址 }, }); const emits = defineEmits(["close", "share"]);
- 分享方法定義
// 方法 // 分享列表 const shareList = computed(() => { let newList = [], mnp = ["qq", "qzone", "wechat", "friend"]; // #ifdef H5 newList = shares.list.filter((s) => s.val != "more"); // #endif // #ifdef MP-WEIXIN newList = shares.list.filter((s) => mnp.includes(s.val)); // #endif // #ifdef APP-PLUS newList = shares.list; // #endif return newList; }); // 打開 function open(options) { let defaultOptions = { dir: "down", radius: 0, width: 500, height: 300, title: "", url: "", }; let params = { ...defaultOptions, ...options }; shares.show = true; shares.options = { ...params }; shares.info = { title: params.title, url: params.url, }; showTimer.value = setTimeout(() => { shares.showMask = true; shares.showBox = true; clearTimeout(showTimer.value); }, showTime.value); } // 關(guān)閉 function close(from = "") { shares.showBox = false; emits("close", from); showTimer.value = setTimeout(() => { shares.showMask = false; clearTimeout(showTime.value); }, showTime.value); showCloseTimer.value = setTimeout(() => { shares.show = false; clearTimeout(showCloseTimer.value); }, showCloseTime.value); } // 分享出去 function shareSet(info) { // 通知父組件 emits("share", info); // 分享內(nèi)容 let url = shares.info.url, title = shares.info.title; // 網(wǎng)頁分享 // #ifdef H5 url = url || location.href; title = title || document.title; // #endif // 分享提示 if (info.val == "more") { // #ifdef APP-PLUS uni.shareWithSystem({ type: "text", summary: title, href: url, success() { uni.showToast({ title: "分享成功!", icon: "success", }); }, fail() { uni.showToast({ title: "分享失敗!", icon: "error", }); }, }); // #endif } else if (info.val == "link") { uni.setClipboardData({ data: url, success() { uni.showToast({ title: "復(fù)制成功!", icon: "success", }); }, }); } else { let shareUrl = info.url(url, title); if (shareUrl) { // #ifdef H5 window.open(shareUrl); // #endif // #ifdef APP-PLUS if (plus) { plus.runtime.openURL(shareUrl, (res) => { console.log("shareUrl res:", res); }); } // #endif } else { // #ifdef APP-PLUS const scene = "WXSceneSession", params = { href: "https://blog.example.com", title: "列表頁面", summary: "我正在使用HelloApp,趕緊跟我一起來體驗(yàn)!", imageUrl: "https://blog.example.com/img/03.png", }; // 分享到聊天界面 if (info.val == "wechat") { appShareWx(scene, params); } // 分享到朋友圈 if (info.val == "friend") { scene = "WXSceneTimeline"; appShareWx(scene, params); } // #endif uni.showToast({ title: "分享成功!", icon: "success", }); } } // 關(guān)閉分享 close(); } // #ifdef APP-PLUS // 分享到聊天界面或朋友圈 function appShareWx(scene = "WXSceneSession", info) { let { href, title, summary, imageUrl } = info; uni.share({ provider: "weixin", scene, type: 0, href, title, summary, imageUrl, success: function (res) { console.log("success:" + JSON.stringify(res)); }, fail: function (err) { console.log("fail:" + JSON.stringify(err)); }, }); } // #endif defineExpose({ open, close, });
H5 和 App
寫好分享組件后,可以在 H5 和 App 里面使用了,下面是頁面模板和腳本使用方法。
模板使用
<!-- 頂部導(dǎo)航組件引入 --> <q-navbar :center="navConfig.center" :right="navConfig.right" @change="changeNav" /> <!-- 分享組件引入 --> <q-share ref="mineShare" @share="shareSetting" />
腳本使用
點(diǎn)擊右上角分享圖標(biāo),調(diào)用下面方法進(jìn)行分享。
- 定義數(shù)據(jù)
// 頂部導(dǎo)航配置 const navConfig = reactive({ center: { show: true, name: "列表頁面", }, right: { show: true, icon: "more", type: "self", }, }); // 分享信息配置 let shareInfo = reactive({ dir: "down", radius: 20, height: 350, title: "列表頁面", url: "https://blog.example.com/#/pages/index/list?from=share", });
- 方法調(diào)用
// 點(diǎn)擊導(dǎo)航分享圖標(biāo)調(diào)用分享方法 function changeNav(info) { if (info.from == "right" && info.icon == "more") { if (proxy.$refs.mineShare) { proxy.$refs.mineShare.open(shareInfo); } } } // 分享組件返回分享信息 function shareSetting(info) { console.log("分享消息:", info); // 分享消息: Proxy(Object) {id: 4, name: '微信', val: 'wechat', url: ?} }
小程序
在這里特別說明一下小程序,由于 uniapp 不支持小程序的 API,因此這里根據(jù)小程序的文檔封裝了一個(gè)獲取小程序參數(shù)的方法放在scripts
的utils
文件中。
獲取參數(shù)
// 獲取微信分享信息 function getWxShare(options) { let pages = getCurrentPages(), page = pages[pages.length - 1], defaultOptions = { title: "HelloApp", path: `/${page.route}`, imageUrl: "", query: "from=list", promise: null, type: "message", // message 聊天界面,friend 朋友圈,favorite 收藏 res: {}, }; let params = { ...defaultOptions, ...options, }; const { title, imageUrl, path, query, promise } = params; const message = { path: `${path}?${query}`, imageUrl, title, promise, }; const friend = { path, query, imageUrl, title, }; const favorite = { title, imageUrl, query, }; const shares = { message, friend, favorite, }; const result = shares[params.type]; console.log(`獲取微信小程序分享參數(shù)${params.type}:`, result); return params; }
引入 API
接著就是頁面引入 uniapp 的 API 和微信分享方法。
import { onLoad, onShareAppMessage, onShareTimeline, onAddToFavorites } from "@dcloudio/uni-app";
獲取參數(shù)
onLoad((option) => { // #ifdef MP-WEIXIN // 設(shè)置微信分享 setWxShare(); // #endif }); // #ifdef MP-WEIXIN // 設(shè)置微信分享 function setWxShare(type = "message") { const params = proxy.$apis.utils.getWxShare({ title: "列表頁面", query: "from=list", type, }); return params; } // #endif
監(jiān)聽轉(zhuǎn)發(fā)事件
// #ifdef MP-WEIXIN // 轉(zhuǎn)發(fā)到聊天界面 onShareAppMessage((res) => { const params = setWxShare("message"); return params; }); // 轉(zhuǎn)發(fā)到朋友圈 onShareTimeline((res) => { const params = setWxShare("friend"); return params; }); // 添加到收藏 onAddToFavorites((res) => { const params = setWxShare("favorite"); return params; }); // #endif
案例展示
- h5 端效果
- 小程序端效果
- APP 端效果
最后
以上就是自定義分享組件的主要內(nèi)容,更多關(guān)于uniapp自定義分享組件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
關(guān)于JavaScript數(shù)組對(duì)象去重的幾種方法
這篇文章主要介紹了關(guān)于JavaScript數(shù)組對(duì)象去重的幾種方法,不管是map對(duì)象的特性還是reduce方法都是很好用的去重方法,需要的朋友可以參考下2023-04-04js輸入框使用正則表達(dá)式校驗(yàn)輸入內(nèi)容的實(shí)例
下面小編就為大家?guī)硪黄猨s輸入框使用正則表達(dá)式校驗(yàn)輸入內(nèi)容的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02typescript編寫微信小程序創(chuàng)建項(xiàng)目的方法
這篇文章主要介紹了typescript編寫微信小程序創(chuàng)建項(xiàng)目的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01JavaScript表單驗(yàn)證的兩種實(shí)現(xiàn)方法
這篇文章主要為大家詳細(xì)介紹了JavaScript表單驗(yàn)證的兩種實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02JavaScript之IE的fireEvent方法詳細(xì)解析
剛開始我以為是會(huì)跟平時(shí)使用onclick()一樣,沒想到最近在寫javascript入門ppt的時(shí)候發(fā)現(xiàn)了,原來自己太自以為是了!看來還有很多javascript的細(xì)節(jié)沒有掌握好啊2013-11-11