最近新作一個功能,須要在小程序中顯示文章,那麼後臺編輯,確定就會採用富文本編輯器。返回到小程序的將會是html
。可使用兩個方法,第一個使用小程序引入 web-view頁面,這麼作會很方便,可是若是文章圖片比較多,並且又沒有什麼規則的話,適配起來就比較蛋疼,後臺編輯也比較蛋疼,並且我是一個後端工程師喲,你懂得。因此採用了第二個方法,使用 wxParse,那麼圖片我就能夠很方便處理了。還有我小程序使用了wepy
框架。
wepy
這個本身看一下文檔就知道了,我主要是不想寫一堆回調,並且它支持async/await
,不使用這些話,我估計登陸就能讓你callback
到崩潰,app.wpy
幾個主要函數:html
僞代碼喲,你懂得,若是對你有幫助,不要複製粘貼
constructor () { super() //這兩個是引入promise,還有修復微信原生同時發送多個請求可能會出現錯誤的bug this.use('requestfix'); this.use('promisify'); //全局攔截與後端請求的數據,這也是爲何會在app.wpy我要寫一個commentRequest方法的緣由 this.intercept('request', { config (p) { return p; }, success (response) { if (response.data.code == 200) { return response.data.data } if(response.data.code==400){ wepy.showModal({ title:'出錯了。。', content:'請下拉從新加載頁面' }); wepy.clearStorageSync(); } }, fail (response) { return response; } }); }
onShow
方法中://全局中設置isRefresh爲false globalData = { userInfo: null, //用戶信息 isRefresh:false } //當用戶進入小程序的時候,查看是否須要refresh_token,若是能獲取到緩存中的reflresh_token,那麼從新請求後端,獲取access_token和reflresh_token,若是reflesh_token都沒有獲取到,說明用戶登陸出現問題了,從新調取login,這裏的is_reflesh是結合下文中的commonRequest使用。 onShow(){ let refreshToken = wx.getStorageSync('refresh_token'); console.log('小程序初始化---------------') if (refreshToken) this.globalData.isRefresh=true; }
這個函數的做用是:當你在
pages
頁面和後端交互時,能夠全局控制
async commonRequest (url, data = '', method = 'POST') { //結合onshow,若是isRefresh爲true,從新請求後端接口獲取數據 if(this.globalData.isRefresh){ if( ! await this.refreshTokenFunc()){ return false; } this.globalData.isRefresh=false; } let value = wx.getStorageSync('access_token') let params = { url: url, data: data, method: method, header: { 'Authorization': value ? ('Bearer ' + value) : '', 'Accept': 'application/json', 'Content-Type': 'application/json' } } return await wepy.request(params); }
refleshTokenFunc
方法:node
async refreshTokenFunc(){ let refreshToken = wx.getStorageSync('refresh_token') let params={ url:urlList.refreshToken, data:{ refresh_token: refreshToken }, method:"POST" } return await wepy.request(params).then(res => { console.log('刷新token 中'); try { wepy.setStorageSync('access_token', res.access_token) wepy.setStorageSync('refresh_token', res.refresh_token); return true; } catch (e) { return false; } }).catch(res => { return false; }); }
login
方法:本身維護用戶登陸狀態:
async login () { try { let {code: code} = await wepy.login(); let {iv: iv, encryptedData: encryptedData, userInfo: userInfo} = await wepy.getUserInfo({withCredentials: true}) let loginData = {code: code, iv: iv, encryptedData: encryptedData} let params={ url:urlList.miniLogin, //本身服務器維護用戶登陸狀態地址 data:loginData, method:"POST", header: { 'Accept': 'application/json', 'Content-Type': 'application/json' } } return await wepy.request(params).then(res => { this.globalData.userInfo = userInfo try { wepy.setStorageSync('access_token', res.access_token) wepy.setStorageSync('refresh_token', res.refresh_token) return true; } catch (e) { return false; } }).catch(res => { console.log('error'); return false; }) } catch (err) { return await this.checkSettingStatus(); } }
async checkLoginState () { try { //微信本身的code 狀態 let wxLoginState = await wepy.checkSession().then(res => {return true}, res => {return false}); //本身服務器的狀態 let token = wx.getStorageSync('access_token') if (!wxLoginState || !token) { return await this.login(); } else { return true; } } catch (res) { console.log('檢查登陸狀態---checkLoginState'); } }
async checkSettingStatus () { // 判斷是不是第一次受權,非第一次受權且受權失敗則進行提醒 try { let auth = await wepy.getSetting(); let authSetting = auth.authSetting; if (authSetting['scope.userInfo'] === false) { let confirm = await wepy.showModal({ title: '用戶未受權', content: '如需正常使用功能,請按肯定並在受權管理中選中「用戶信息」,而後點按肯定。最後再從新進入小程序便可正常使用。', showCancel: false, }); if (confirm.confirm) { await wepy.openSetting(); return await this.login(); } else { return false; } } else { return true; } } catch (res) { } }
主頁面app.wpy
就這麼多東西,在pages
頁面中怎麼使用呢,好比下面就是你小程序的入口pages
文件了,用戶訪問的時候會首先進入:git
onLoad () { this.list(); wx.showLoading({ title: '加載中', icon:'loading', mask:true }) } onShareAppMessage(res){ return { title:'xxx服務歡迎您的使用', path:'/pages/list' } } onPullDownRefresh () { wx.showNavigationBarLoading() this.list(); wx.showToast({ title:'加載中', icon:'loading', mask:true }) wx.hideNavigationBarLoading() wx.stopPullDownRefresh() } async list () { //檢查小程序登陸,查看上文中的checkLoginState,若是登陸狀態失效,那麼從新掉起login 方法登陸 await this.$parent.checkLoginState(); //調用全局的請求函數 await this.$parent.commonRequest(url.list).then(res => { this.xxx = res; this.$apply(); wx.hideLoading(); }).catch(err=>{ wepy.showModal({ title:'走神了。。', content:'請下拉從新加載頁面' }) wx.clearStorageSync('access_token') }) }
咱們來講一下整個訪問流程,用戶一打開小程序,首先通過app.wpy
中的onLauch
方法,而我沒有寫任何東西,那麼就會訪問onShow
方法,在這個函數裏,第一次訪問確定沒有reflesh_token
,因此isRefresh
確定爲false,那麼接下來進入pages
中的首頁了,就會進入上面的list
函數,就會調用 await this.$parent.checkLoginState()
,天然就會調用login
了,是否是很機智。github
wepy就簡單介紹這麼點了web
wxParse
按照官網引入就能夠了,可是結合wepy,就會出現問題,那麼下面就是解決bug問題:
若是已經安裝官網引入了,發現圖片不能自適應,或者內容都不能顯示,爲何呢,找到wxParse.js
文件中wxParse
函數,最下面看到:json
問題就出在這裏,wepy
和微信自帶的數據綁定有衝突,wxParseImgLoad
和wxParseImgTap
是自動適應圖片和圖片加上點擊事件的,改爲下面:小程序
that[bindName]=transData
發現圖片仍是不能使用,那麼去掉wxParseImgLoad
和wxParseImgTap
,把這兩個函數放到pages
中須要使用wxparse
的頁面中:後端
methods={ // 圖片點擊事件 wxParseImgTap(e) { let that = this; let nowImgUrl = e.target.dataset.src; let tagFrom = e.target.dataset.from; if (typeof (tagFrom) != 'undefined' && tagFrom.length > 0) { wx.previewImage({ current: nowImgUrl, // 當前顯示圖片的http連接 urls: that.data[tagFrom].imageUrls // 須要預覽的圖片http連接列表 }) } }, /** * 圖片視覺寬高計算函數區 **/ wxParseImgLoad(e) { }
修改wxparse.wxml
中的img
模板,原來是:promise
<template name="wxParseImg"> <image class="{{item.classStr}} wxParse-{{item.tag}}" data-from="{{item.from}}" data-src="{{item.attr.src}}" data-idx="{{item.imgIndex}}" src="{{item.attr.src}}" mode="aspectFit" bindload="wxParseImgLoad" bindtap="wxParseImgTap" mode="widthFix" style="width:{{item.width}}px;"--> </template>
改爲:緩存
<template name="wxParseImg"> <image class="{{item.classStr}} wxParse-{{item.tag}}" lazy-load="true" data-from="{{item.from}}" data-src="{{item.attr.src}}" data-idx="{{item.imgIndex}}" src="{{item.attr.src}}" mode="widthFix" bindload="wxParseImgLoad" bindtap="wxParseImgTap" style="width:100%;" </template>
我這裏使用了微信圖片image
組件自適應的功能,而不用上面那個wxParseImgLoad(e)
去動態計算了。如今知道我爲何去掉那個函數了吧
其實就改動了wxparse
插件中的wxparse.wxml
和wxparse.js
兩個文件。那麼怎麼使用呢:
<template> //-------------------------模板使用------------------------------- <import src="../wxParse/wxParse.wxml"/> <block> <template is="wxParse" data="{{wxParseData:article.nodes}}"/> </block> </view> </template> <script> import wepy from 'wepy' import url from '../config/url'; import WxParse from "../wxParse/wxParse"; export default class newsDetail extends wepy.page { data = { title:'', article_id:'', detail:'', article:'' } methods={ // 圖片點擊事件 wxParseImgTap(e) { let that = this; let nowImgUrl = e.target.dataset.src; let tagFrom = e.target.dataset.from; if (typeof (tagFrom) != 'undefined' && tagFrom.length > 0) { wx.previewImage({ current: nowImgUrl, // 當前顯示圖片的http連接 urls: that.data[tagFrom].imageUrls // 須要預覽的圖片http連接列表 }) } }, wxParseImgLoad(e) { } } onLoad (options) { this.articleDetail(); let {id:id}=options; this.article_id=id; wx.showLoading({ title: '加載中', icon:'loading', mask:true }) } async articleDetail () { //檢查小程序登陸登陸 await this.$parent.checkLoginState(); let urlInfo=url.articleDetaiol await this.$parent.commonRequest(urlInfo).then(res => { this.detail = res; console.log(this.detail) //這裏很重要--------------------------------------------------- WxParse.wxParse('article', 'html', this.detail.content, this,1); this.$apply(); wx.hideLoading(); }).catch(err=>{ wx.clearStorageSync('access_token') }) } } </script>
至於後臺怎麼抓取微信文章,把圖片上傳到七牛,有時間另寫吧