最近菜鸟又来开发微信小程序了,感觉只要一段时间不搞微信小程序,再来搞必出问题,且代码不熟练,一些封装的东西都要去别的项目里面找,所以这里菜鸟直接总结一下,方便后续开发微信小程序!
常见代码
这里菜鸟暂时只总结了网络请求的封装,因为菜鸟开发的微信小程序都不是很难,基本上只有2-3个页面,只是完成部分简单工作而已!
后续如果开发更难的微信小程序,菜鸟会回来这里补充。
网络请求封装
request.js
const BASE_URL = 'http://172.16.40.26:8085'
const myrequest = (obj) => {
wx.showLoading({
mask: true,
title: '加载中...',
})
return new Promise((resolve, reject) => {
wx.request({
url: BASE_URL + obj.url,
data: obj.data ? obj.data : null,
header: obj.header ? obj.header : {'content-type': 'application/json'},
method: obj.method ? obj.method : "GET",
responseType: obj.responseType ? obj.responseType : '',
success: (result) => {
console.log(result)
if (result.statusCode == 200) {
resolve(result.data);
} else {
reject(result.errMsg)
}
},
fail: (err) => {
reject("服务器连接异常,请检查网络再试");
},
complete: ()=> {
wx.hideLoading();
}
})
})
}
module.exports = {
myrequest,
}
使用
const {myrequest} = require("./request.js")
function loginApi(params) {
return myrequest({
url: '/login',
method: 'POST',
data: params
})
}
module.exports = {
loginApi,
}
封装的loginApi使用
const { loginApi } = require("../../network/api.js")
Page({
data: {
contractNum: ''
……
}
})
自定义导航栏
这里菜鸟已经写过了,直接参考:微信小程序 自定义导航栏
实现键盘吸附效果
登录界面代码,这里主要看 重点代码 就行,不好单独提出来,所以就整个搬过来了,希望各位读者可以接受!
login.wxml
<!--pages/login/login.wxml-->
<view
class="navtitleBox"
style="padding-top:{{headerHeight}}px"
>
<view class="title">
<text>XXXXlims系统</text>
</view>
<image class="loginBg" src="../../imgs/loginBg.png" mode="widthFix"></image>
<!-- 重点代码 -->
<view class="loginForm" style="bottom: {{formposition}}rpx">
<view class="formTitle">
<text>欢迎登录</text>
</view>
<view class="formView">
<form catchsubmit="formSubmit">
<view class="page-section">
<view class="page-section-title">用户名:</view>
<input class="weui-input" bindkeyboardheightchange="focusFun" bindblur="getUsernameFun" placeholder="请输入用户名" />
</view>
<view class="page-section">
<view class="page-section-title">密码:</view>
<input class="weui-input" password bindkeyboardheightchange="focusFun" bindblur="getPasswordFun" placeholder="请输入密码" />
</view>
<view class="btn-area">
<button type="primary" formType="submit">登录</button>
</view>
</form>
</view>
</view>
</view>
login.wxss
/* pages/login/login.wxss */
page {
height: 100vh;
overflow: hidden;
}
.navtitleBox {
background-color: #3f8cff;
height: 100%;
}
.title {
text-align: center;
transform: translateY(-50%);
color: #fff;
}
.loginBg {
width: 100%;
}
// 重点代码
.loginForm {
width: 100%;
position: absolute;
background-color: #3f8cff;
}
.formTitle {
color: #fff;
font-size: 50rpx;
text-align: center;
margin-top: 80rpx;
margin-bottom: 50rpx;
}
.formView {
box-sizing: border-box;
background-color: #fff;
width: 85%;
margin: auto;
border-radius: 20rpx;
display: flex;
flex-direction: column;
align-items: center;
padding: 50rpx;
}
.page-section {
display: flex;
align-items: center;
line-height: 80rpx;
margin: 30rpx;
}
.page-section-title {
width: 150rpx;
text-align: center;
}
.weui-input {
width: calc(100% - 150rpx);
border-bottom: #000 2rpx solid;
}
.btn-area {
margin: 60rpx 0 30rpx;
}
login.js
import {loginApi} from '../../network/api'
const app = getApp()
Page({
data: {
headerHeight: app.globalData.headerHeight,
formposition: 260,
username: null,
password: null,
},
// 重点代码 --》 有点bug,就是点击回车缩起来可以,但是点击那个键盘右上方的下箭头缩起来的时候就有问题
focusFun(e) {
this.data.formposition = 260
this.setData({
formposition: e.detail.height === 0 ? 260 : this.data.formposition + e.detail.height
})
},
getUsernameFun(e) {
this.data.username = e.detail.value
},
getPasswordFun(e) {
this.data.password = e.detail.value
},
async formSubmit() {
let res = await loginApi(this.data.username,this.data.password)
if(res.status === 200) {
app.globalData.userInfo = res
return
}
wx.showToast({
title: res,
icon: "none",
duration: 1000
})
},
})
微信小程序 使用formdata请求大坑
菜鸟做这个登录的时候,发现后端接收的不是 json 对象格式,而是 formdata 格式,一问才知道是后端使用的框架搞成这样的,那没办法,后端不好改,就只能前端扛下所有了!
(建议还是后端改,直接怼回去,狗头保命!)
然后菜鸟在微信小程序社区一搜,果然不是菜鸟一个人遇见了,而且也真的有解决办法,这里感谢该文章:使用wx.request发送multipart/form-data请求的方法
菜鸟下面的就是直接取自该文章!
如果 wx.request 中仅指定 'content-type' 为 'multipart/form-data',服务端会报"no multipart boundary was found"的错误,就像这个帖子里描述的:developers.weixin.qq.com/community/d…
尽管指定了 content-type 为 'mutipart/form-data' ,但是 wx.request 并不会为我们自动添加 boundary,既然如此,我们自己加不就可以了吗?经过测试,确认了这个方法可行,前端示例代码如下:
wx.request({
url:'http://localhost:8080/test/multipart-form',
method:'POST',
header: {
'content-type':'multipart/form-data; boundary=XXX'
},
data:'\r\n--XXX' +
'\r\nContent-Disposition: form-data; name="field1"' +
'\r\n' +
'\r\nvalue1' +
'\r\n--XXX' +
'\r\nContent-Disposition: form-data; name="field2"' +
'\r\n' +
'\r\nvalue2' +
'\r\n--XXX--'
})
这里,我向服务端传递了两个参数:field1=value1, field2=value2!
注意
这里必须按照这个格式来,单双引号都不能变,菜鸟就是自己打了一次,用的双引号包裹的单引号,结果 formdata 中就获取不到值了!
菜鸟的代码
api.js
import {myrequest} from './request'
function loginApi(username,password) {
return myrequest({
url: '/login',
method: 'POST',
header: {'content-type': 'multipart/form-data; boundary=XXX'},
data: '\r\n--XXX' +
'\r\nContent-Disposition: form-data; name="username"' +
'\r\n' +
'\r\n'+ username +
'\r\n--XXX' +
'\r\nContent-Disposition: form-data; name="password"' +
'\r\n' +
'\r\n' + password +
'\r\n--XXX--'
})
}
module.exports = {
loginApi,
}
结合上面的 login.js 看,前端传递过去的值正确
微信小程序每次request请求,Cookie不一样?
这次做微信小程序,发现和后台建立连接,每次都会新建一个连接,这样就无法在同一个连接上进行操作,那么后台中的数据,后台就无法通过缓存进行传输,所以必须得解决这个问题。
解决办法
//保存cookies,解决request每次请求连接不一样的bug
const phpsessidarr = result.cookies[0].split(";"); //这里result是后台第一返回的,可以从中获取到cookies
const phpsessid = phpsessidarr[0];
const header = {'content-type': 'application/json', 'Cookie': phpsessid};
wx.request({
url: common_urlapi+url,
data:{},
header: header,
method:"POST",
success:res=>{},
fail:err=>{}
)}
其它更多参数设置:
注意:
菜鸟最近在公司开发微信小程序,发现并没有发现这个问题,一问才知道,原来是因为之前大学做这个项目的时候,老王保存了会话信息,所以cookie是老王设置并返回,后面又要通过cookie获取东西的,所以才会有上面每次建立新连接导致cookie不一样的情况出现!
后端分析的原因:
我和前端小程序交互,由于微信小程序的内部原因,每一次与我后端建立会话后,微信小程序并没有维持这段会话,而是每一次请求都是一个新的会话,这就导致不能正常维持前后端交互流程。后来经过分析,微信小程序在http请求头cookie加上我后端发过来的session_id就可以了,这一点和浏览器不一样,浏览器会默认保存session_id,每次请求都会带上上一次的session_id维持会话。