Recently, a new function has been created that needs to display articles in a small program, then the background editor will definitely use a rich text editor. It will be back to the applethtml
. You can use two methods. The first one is to use a small program to introduce a web-view page. This will be very convenient. However, if there are many pictures in the article, and there are no rules, it will be more painful to adapt and the background editing will be more. It hurts, and I'm a backend engineer, you know. So using the second method, using wxParse , then I can easily deal with the picture. I also use a small programwepy
framework.
Brieflywepy
I know this by looking at the documentation myself. I mainly do n’t want to write a bunch of callbacks, and it supports it async/await
. Without using these words, I estimate that logging in can callback
crash you to a app.wpy
few main functions:
Pseudo code, you know, if it helps you, do n’t copy and paste
Constructor method:
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. In the onShow
method:
//全局中设置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. Global request function
The role of this function is: when you are in
pages
time and back-end interactive pages, can global control
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
method:
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
Method:
Maintain user login status yourself:
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. Check the login status:
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. Determine whether to authorize:
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) {
}
}
There app.wpy
are so many things on the main pages
page, how to use it in the page, for example, the following is the entry pages
file of your applet , the user will first enter when accessing:
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')
})
}
Let app.wpy
's onLauch
talk about the entire access process. As soon as the user opens the applet, the first method is passed , and I didn't write anything, then I will access the onShow
method. In this function, the first access is definitely not reflesh_token
, so it is isRefresh
definitely false, Then, when you enter pages
the homepage in the middle, you will enter the above list
function, you will call it await this.$parent.checkLoginState()
, and you will naturally call login
it, is it very clever?
wepy will briefly introduce this point
IntroducewxParse
It can be introduced according to the official website, but when combined with wepy, problems will occur, then the following is to solve the bug problem:
If it has been introduced by the official website, and it is found that the picture cannot be adapted or the content cannot be displayed, why do you find the function in the wxParse.js
file wxParse
, see at the bottom:
The problem lies here, wepy
there is a conflict with the data binding that comes with WeChat, wxParseImgLoad
and it wxParseImgTap
is automatically adapted to the picture and the picture plus the click event, changed to the following:
that[bindName]=transData
Found that the picture is still not available, then remove the wxParseImgLoad
sum wxParseImgTap
and put these two functions into the page that pages
needs to be used 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
The img
template under modification turned out to be:
<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>
Change to:
<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>
I used the image
adaptive function of the WeChat picture component here , instead of the wxParseImgLoad(e)
dynamic calculation above . Now I know why I removed that function
In fact, it changes the wxparse
plug-in wxparse.wxml
and wxparse.js
the two files. So how to use it:
<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>
As for how to grab the WeChat article in the background, upload the picture to Qi Niu, have time to write another
This article is reproduced in: How to display html content in a small program