最近新做一个功能,需要在小程序中显示文章,那么后台编辑,肯定就会采用富文本编辑器。返回到小程序的将会是html
。可以使用两个方法,第一个使用小程序引入web-view页面,这么做会很方便,但是如果文章图片比较多,而且又没有什么规则的话,适配起来就比较蛋疼,后台编辑也比较蛋疼,而且我是一个后端工程师哟,你懂得。所以采用了第二个方法,使用wxParse,那么图片我就可以很方便处理了。还有我小程序使用了wepy
框架。
简单说一下wepy
这个自己看一下文档就知道了,我主要是不想写一堆回调,而且它支持async/await
,不使用这些话,我估计登录就能让你callback
到崩溃,app.wpy
几个主要函数:
伪代码哟,你懂得,如果对你有帮助,不要复制粘贴
构造函数方法:
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;
}
});
}
1. 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;
}
2.全局请求函数
这个函数的作用是:当你在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
方法:
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;
});
}
3.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();
}
}
4.检查登录状态:
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');
}
}
5.判断是否授权:
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
文件了,用户访问的时候会首先进入:
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
了,是不是很机智。
wepy就简单介绍这么点了
引入wxParse
按照官网引入就可以了,但是结合wepy,就会出现问题,那么下面就是解决bug问题:
如果已经安装官网引入了,发现图片不能自适应,或者内容都不能显示,为什么呢,找到wxParse.js
文件中wxParse
函数,最下面看到:
问题就出在这里,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
模板,原来是:
<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>
至于后台怎么抓取微信文章,把图片上传到七牛,有时间另写吧
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。