距離第一篇的發佈過了很久,由於此次真的踩了很多坑..之後仍是儘可能不要新立項目好了,就跟立了個flag同樣T Thtml
本篇主要內容有如下幾點--vue
首先介紹一下項目的背景,脫離了背景談需求都在瞎逼逼,本次活動頁是獨立於主站項目(SPA)的新獨立項目,可是因爲對微信的強依賴,新項目仍是須要掛在主域名下。nginx
這有啥的,讓運維同事幫忙配個nginx把主站的某個路徑指向新項目目錄就好唄~事實上確實是的,一開始配的域名是m.kurisu.fm/my(對..這個是假域名)凡是這個路徑的都直接指向vue項目的目錄,很完美跑起來了,這個也是微信的安全域名因此登陸應該也是穩妥的。可是問題來了...它無法支付...這個域名並非可支付的域名,因此咱們必需要改動域名。vue-router
咱們的可支付路徑是m.kurisu.fm/pay/:id,只好再麻煩一下同事幫忙配個m.kurisu.fm/pay/my的路徑了,好啦,restart以後一看,涼了。白屏,靜態資源都加載出來了,#app也掛載上了,可是router-view那邊沒有顯示。這是啥玩意?看了下vue-router的文檔,發現了這個玩意--應用基路徑也就是說咱們應該將router的配置修改一下後端
let link = ''
if (window.location.host === 'm.kurisu.fm') {
link = '/pay/my'
}
export default new Router({
base: link, // 在此設定應用的基路徑
/*在window.location.host === 'm.kurisu.fm'的狀況下,路由會將path爲'/'的路徑變爲'/pay/my',若是沒有這個配置的話router仍是會按'/'的路徑去匹配路由,這樣用戶將會沒法正常訪問到頁面*/
routes: [
{
path: '/',
name: 'JXGlobal',
component: JXGlobal
},
{
path: '/auth',
component: Auth
}
]
})
複製代碼
修改以後咱們就能夠愉快的進行下面的開發啦~並且還能夠悄咪咪的在線上跑微信的各個功能[冷漠]api
說到了router就必然少不了對mode的討論了,這裏兩種模式我都想說一說,由於實際開發中都TM用到了,最後我得出的結論是--強烈建議使用hash路由緩存
雖然最後我仍是用了history的模式因爲項目的歷史緣由,這次開發仍是使用了history的模式,具體緣由會在下闡述。安全
vue-router 默認 hash 模式 —— 使用 URL 的 hash 來模擬一個完整的 URL,因而當 URL 改變時,頁面不會從新加載。bash
使用這種模式的時候,你們會發現url會出現一個很奇葩的'#',可是這個模式除了醜了點,真的沒有啥問題。特別是在微信上面跑單頁應用的時候,簡直是良心之選。微信
可是爲何最後我沒有采用這個模式呢?下面我仍是想結合一下項目的實際,說說我選擇的緣由--
根本緣由支付受權目錄限制是最多隻能配置3個,超過3個將沒法配置,而且路徑深度不能大於2層用了hash以後咱們的url後面都會有'#/'這樣就致使微信支付時匹配的目錄有問題。通過測試,微信貌似以後根據'/'來判斷路徑層級的,因此若是使用了'#/'就表明自然少了一層路徑,權衡以後仍是放棄了使用hash模式
關於History模式路由的介紹也已經爛大街了,它主要是依靠HTML5新增的API--history.pushState來實現的,具體實現就不在這裏囉嗦了,往後爭取出一篇router的詳解。
因爲種種緣由(詳情見上方Hash部分)我選擇了history模式跑這個項目,在這期間也是遇到了一些坑的地方。
由於項目主要是跑在微信上的,總的來講坑的地方就是微信JSSDK對單頁應用的兼容差強人意
iOS上微信不會根據history.pushState來更改當前的href這致使的問題可很多,複製連接是錯誤的、受權可能會不成功、支付會有問題;在安卓上則一點問題都沒有。解決方案仍是比較粗暴的,在iOS系統中,斷定到須要和微信JSSDK交互的頁面就強行刷新一下以保證交互的正常進行。
測試支付的時候發現一個頗有趣的現象,在iOS跑得妥妥的支付調起,到安卓就掛了。在安卓系統中,支付調起了,可是最終付款的彈窗卻沒出現。對比了兩端的支付參數也是如出一轍,問題出在哪呢?掙扎了許久,仍是在網上找到了坑友們的回答--安卓調起支付的url不容許'/'結尾,不然支付將會沒法正常調起
因爲router有兩種模式,因此處理起來也有些許差別,不過總的來講仍是一致的。
首先,咱們最好有一個獨立的頁面(組件)來處理受權相關的事件,由於實際開發的狀況是可能同時存在多種不一樣途徑的受權,有一個獨立頁面有助於咱們很好的與主業務解耦。
而後就是看看微信的文檔把受權的連接拼起來,這裏須要注意的是redirect_uri必需要設定過白名單的域名,不然是無法正常發起受權的。
能正常的重定向到指定的url以後,恭喜你,你已經完成了受權處理的1%一大步啦。重定向的url會帶有code(&state...),咱們只須要拿着這個code向後端請求登陸數據便可。
在這一步,兩種路由模式的處理方式就有些許不一樣了。
history模式下,咱們能夠直接經過$route.query來拿到相關的參數,而後能夠繼續後面的請求。這是沒有將受權分離的作法,可是在此次的項目中,我仍是分離出了一個單獨的受權頁面,這也給本身埋了很多坑。首先是router.push的用法,一開始測試的時候能夠順利的從微信受權的頁面回來,可是回來就不動了,即不請求登陸接口,也不重定向回原頁面。後面發現是code被沖掉了,罪魁禍首就是我本身router.push,在push的時候沒將參數帶上。另一個須要注意的是受權完成以後最好使用window.location.href來進行原頁面的回跳,能夠避開一些在iOS系統下jssdk的坑。
hash模式下,咱們則不須要像history模式那樣到處避坑,可是這裏咱們會發現沒法用$route.query拿到想要的參數,那是由於從微信跳回來以後咱們的url變成了這樣-- m.kurisu.fm/?code=1234#/ 發現問題了嗎?'#/'加到了最後,致使$route無法拿到'#/'以前的code,這裏只須要本身寫個解析window.location.search的工具類就能夠輕鬆解決啦。
function urlQuery2Object (search) {
let result = {}
search.split('?')[1].split('&').forEach(function (part) {
let item = part.split('=')
result[item[0]] = decodeURIComponent(item[1])
})
return result
}
複製代碼
因爲發起支付的路徑有所限制,活動頁的二級頁面甚至是主頁都不能獨佔一層路由,這該怎麼解決呢?最快捷的解決方案就是經過route.query和watch對route的監聽來實現頁面切換。
最後敲定的url是這樣的m.kurisu.fm/pay/my?:id&:sid其中id是此次活動的id(可能會同時有多個活動使用同一套頁面),sid則是每一個活動下的子活動頁面。
<div class="container__content" v-if="activity_init">
<keep-alive>
<jx-index :f_content="init_data" v-if="!$route.query.sid"></jx-index>
<jx-subpage v-else></jx-subpage>
</keep-alive>
</div>
複製代碼
在頁面展現上咱們只需判斷頁面是否存在sid就能夠知道應該展現哪一個template,而後對$route的監聽則只須要在子活動頁面的template中進行。
watch: {
//監聽$route的變更
'$route' (to, from) {
if (to.query.sid && (to.query.sid !== from.query.sid)) {
//對子活動頁的緩存,如有緩存則優先使用緩存數據,並靜默(無loading toast)請求新數據,優化頁面體驗
if (window.sessionStorage.getItem(String(to.query.id) + String(to.query.sid))) {
let data = window.sessionStorage.getItem(String(to.query.id) + String(to.query.sid))
this.column = JSON.parse(data)
this.page_init = true
this.GetData(false)
} else {
this.GetData(true)
}
}
}
}
複製代碼
本系列文章主要仍是記錄實際開發過程當中的一些解決方案,本篇主要是圍繞在路由相關的問題以及微信在其中的兼容問題,但願能幫助你們和我規避往後的坑。