微信把服務号的模闆消息改成了訂閱通知,而訂閱通知是用開放标簽
wx-open-subscribe
來訂閱,而不管是在官方文檔,還是在社群的文章中,都隻有普通 Vue 項目的用法,是以今天專門記錄一下如何在 Nuxt.js 項目中,跟原有的 Element UI 一起搭配使用微信開放标簽。
跟着官方文檔的使用步驟走,因為開放标簽使用步驟與微信 JS-SDK 類似,是以很多工作都不需要做,像
JS接口安全域名
之前已經配置過。然後引入 JS 檔案,之前我用的是 1.4.0 版本的,現在換成 1.6.0 版本,這個 JS 檔案我是在 nuxt.config.js 檔案中引入的。
module.exports = {
head: {
script: [
{src: 'https://res.wx.qq.com/open/js/jweixin-1.6.0.js'}
]
}
}
然後下一步,通過 config 接口注入權限驗證配置并申請所需開放标簽。這個因為之前要用 jsApi,是以也做過,隻需要在裡面加上需要的開放标簽即可。我這裡需要跳轉小程式和服務号訂閱通知 2 個開放标簽。
wx.config({
debug: true, // 開啟調試模式,調用的所有api的傳回值會在用戶端alert出來,若要檢視傳入的參數,可以在pc端打開,參數資訊會通過log打出,僅在pc端時才會列印
appId: '', // 必填,公衆号的唯一辨別
timestamp: , // 必填,生成簽名的時間戳
nonceStr: '', // 必填,生成簽名的随機串
signature: '',// 必填,簽名
jsApiList: [
'updateAppMessageShareData',
'updateTimelineShareData'
], // 必填,需要使用的JS接口清單
openTagList: [
'wx-open-launch-weapp',
'wx-open-subscribe'
] // 可選,需要使用的開放标簽清單
});
這個時候如果你去頁面中使用開放标簽,控制台會報這個錯誤:
Unknown custom element: <wx-open-subscribe> - did you register the component correctly?
。因為開放标簽屬于自定義标簽,Vue 和 Nuxt.js 會給予未知标簽的警告。在普通的 Vue 項目中,可以在 main.js 中配置
Vue.config.ignoredElements = ['wx-open-launch-weapp', 'wx-open-subscribe']
。而在 Nuxt.js 項目中,需要在 nuxt.config.js 中配置。(檢視 nuxtjs 官方文檔)
module.exports = {
vue: {
config: {
ignoredElements: ['wx-open-launch-weapp','wx-open-subscribe']
}
}
}
現在就可以在頁面中去使用開放标簽了。先提醒一句,因為訂閱通知隻有已認證的服務号才可以使用,是以代碼寫好之後,需要部署到生産環境,在手機真機上進行驗證調試,在測試環境以及開發者工具都是沒辦法驗證的。一般我們在開發時,會使用 vconsole 進行調試,而在生産環境下,沒有 vconsole,最好的工具就是 Chrome 浏覽器的 inspect 功能,可以用來調試 Android 手機中的 H5 頁面,不知道的可以了解一下。在官方文檔的使用說明中有提到,對于Vue 等視圖架構,為了避免 template 标簽沖突的問題,可使用
<script type="text/wxtag-template"></script>
代替
<template></template>
,來包裹插槽模版和樣式。是以如果你的開放标簽不顯示,請先檢查是不是這個有問題。在 vue 頁面的
<template></template>
中添加
wx-open-subscribe
。
<template>
<wx-open-subscribe template="QhsDLahvIjb8RAB8iC23-hTbsMtnhIgKNrcgXERTxk0" id="subscribe-btn">
<script type="text/wxtag-template">
<style>.btn { margin:10px; padding: 5px }</style>
<button class="btn">訂閱通知</button>
</script>
</wx-open-subscribe>
</template>
這裡 wx-open-subscribe 的 template 屬性是模闆的 id,訂閱通知的模闆需要先在公衆号背景申請。将上述代碼部署到生産環境之後,就可以在手機上看到按鈕了,同時按鈕點選後,也能彈出申請通知的彈框。
既然已經可以正常顯示按鈕和響應按鈕點選事件了,接下來要考慮的就是怎麼和現有的項目融合。首先,我覺得不應該專門寫個按鈕讓使用者訂閱通知,而是應該當使用者點選之前已有的按鈕時,可以先彈出這個申請通知的彈框,然後使用者允許或取消後,再走下面的流程。舉個例子,我之前有個
購買
按鈕,使用者購買之後我想給使用者發條購買成功的通知,那麼我就應該把訂閱通知的功能加到我這個
購買
按鈕上,而不是再加個按鈕讓使用者專門訂閱這條通知。同時,我可能會在任何一個元件上(不僅僅是 Button,可能是一張圖檔),當使用者點選的時候,申請發送某個通知, 是以這個訂閱通知标簽應該是和其他元件分離的,可以搭配任何元件使用,隻是當使用者點選其他元件的時候,我要觸發這個訂閱功能,彈出這個彈窗。是以樣式這塊就比較頭疼,我項目中用的 UI 架構是 Element UI,我不希望在加這個訂閱通知的時候,還要對我的 Element UI 做改動,那太不合理了,是以最好的處理方法就是把開放标簽和需要添加訂閱功能的那個元件作為兄弟節點,放在同一個父元素 div 裡,然後利用子絕父相,把開放标簽的 position 寫為 absolute,然後父元素的 position 寫為 relative,讓開放标簽覆寫需要添加訂閱功能的那個元件,這樣看着像是點選的那個元件,其實點選的是開放标簽,就可以正常申請通知了,然後把那個元件的點選事件交給開放标簽處理就可以了。總結下來,就是原先的按鈕實作樣式,開放标簽實作申請通知,并處理點選事件。
<div style=""="position: relative;">
<el-button size="medium" type="primary" round style="width:100%;height:100%;">去購買</el-button>
<div class="" style="position:absolute;width:100%;height:100%;top:0px;">
<wx-open-subscribe template="LRN2-ntyTNKhUCtbOlhTfhvLFEXVZHp1zeeftcbc2Q4" id="subscribe-btn"
style="position:absolute;width:100%;height:100%;left:0px;top:0px;overflow:hidden;"
@success="openSubscribeSuccess" @error="openSubscribeError">
<script type="text/wxtag-template">
<style>.btn { width: 100%; height: 500px;}</style>
<div class="btn"></div>
</script>
</wx-open-subscribe>
</div>
</div>
可以看到,在開放标簽裡面的樣式中,我把 height 寫成了 500px,因為插槽中模版的樣式是和頁面隔離的,是以寫成 100% 是不行的,必須得有固定的高度,在社群中,名為猛的這位夥伴是擷取的實際高度,我發現沒必要,隻要我在 wx-open-subscribe 裡面,設定了 overflow,讓内部超出的部分隐藏,就可以正常使用。要注意的是,這裡的高度必須大于等于需要添加訂閱功能的元件高度,這裡我假設的是需要添加訂閱功能的元件高度不超過 500px,否則就不夠了,還得改大一點。然後 wx-open-subscribe 有 success 和 error 兩個事件,我們像 click 點選事件一樣,調用方法就可以了。
到了這裡,開放标簽 wx-open-subscribe 的使用差不多就成功了。但是如果以後很多地方都需要訂閱不同的通知,難道每次都要把這一段代碼複制一遍嗎,這就不太合适了,是以最好的方案是把每個開放标簽都封裝成一個 Vue 元件,然後在每個用到的地方直接引入元件使用就可以了,非常 nice。下面是我 open-subscribe.vue 的内容。
<template>
<div class="wx-open-subscribe-container" style="position:absolute;width:100%;height:100%;top:0px;">
<wx-open-subscribe :template="templateId" id="subscribe-btn" style="position:absolute;width:100%;height:100%;left:0px;top:0px;overflow:hidden;" @success="openSubscribeSuccess" @error="openSubscribeError">
<script type="text/wxtag-template">
<style>.btn { width: 100%; height: 500px;}</style>
<div class="btn"></div>
</script>
</wx-open-subscribe>
</div>
</template>
<script>
export default {
props: {
templateId: {
type: String,
default() {
return ''
}
}
},
methods: {
openSubscribeSuccess(e) {
this.$emit('open-subscribe-success', e.detail)
},
openSubscribeError(e) {
this.$emit('open-subscribe-error', e.detail)
}
}
}
</script>
wx-open-subscribe
有一個屬性 template,是以将其作為 prop,從父元件傳值過來。
wx-open-subscribe
有 2 個事件 success 和 error,是以使用
$emit
,将值傳給父元件,讓父元件處理事件。下面是這個子元件在父元件中的使用。
<template>
<div class="" style="position:relative;">
<el-button type="success" plain icon="el-icon-share" circle />
<open-subscribe
template-id="9KjxFrQpgHpDpvkw3Krk6N8URgPNn7j6inHUeNF0sQg"
@open-subscribe-success="openSubscribeSuccess"
@open-subscribe-error="openSubscribeError"
/>
</div>
</template>
<script>
import openSubscribe from '@/components/open-tags/open-subscribe.vue'
export default {
components: {
openSubscribe
},
methods: {
openSubscribeSuccess(e) {
},
openSubscribeError(e) {
}
}
}
</script>
可以看到,父元件在使用訂閱通知子元件時,把模闆 id 傳進去,然後監聽
open-subscribe-success
和
open-subscribe-error
兩個事件,自己實作兩個時間的處理即可。
至于其他的開放标簽,原理差不多,下面為跳轉小程式的開放标簽封裝的子元件 open-launch-weapp.vue。
<template>
<div class="wx-open-launch-weapp-container" style="position:absolute;width:100%;height:100%;top:0px;">
<wx-open-launch-weapp :username="username" :path="path" id="launch-btn" style="position:absolute;width:100%;height:100%;left:0px;top:0px;overflow:hidden;" @launch="openWeappLaunch" @error="openWeappError">
<script type="text/wxtag-template">
<style>.btn { width: 100%; height: 500px;}</style>
<div class="btn"></div>
</script>
</wx-open-launch-weapp>
</div>
</template>
<script>
export default {
props: {
username: {
type: String,
default() {
return ''
}
},
path: {
type: String,
default() {
return ''
}
}
},
methods: {
openWeappLaunch(e) {
this.$emit('open-weapp-launch')
},
openWeappError(e) {
this.$emit('open-weapp-error')
}
}
}
</script>
到底為止,就實作了在 Nuxt.js 中配合原有的 Element UI 使用微信開放标簽,對之前的東西沒有什麼大的破壞,還算比較合理的,希望可以幫到你。