微信提供的开发工具的编辑功能不是一般的水,写代码肯定不能用它,否则就是浪费生命.不说别的,连自动保存都没有,第一次写时写了一个多小时,后面下班直接关掉,也不弹出提示说没保存.然后第二天过来,写的代码全没了!!! 顿时感到巨坑无比.这些工具开发人员吃干饭的么???
(后来的版本已经修复不能自动保存的问题了,当然编辑功能还是不好用.)
它的正确用法是作为运行和调试工具.
那么适合作为编辑工具的是: webStorm.基于IntelJ内核,开启Dracula主题,跟Android studio的使用习惯非常接近,so cool!各种方法提示,自动保存,快速查找...应有尽有.闭源的微信开发工具就不要用来写代码了,珍惜生命.
webStorm要识别wxml和wxss,还需要配置一下文件类型:(看下面别人截的图)
记住html和css里都要加上微信小程序对应的类型

综上,开发时,用webstorm来写代码,用微信开发工具来运行和调试,速度飕飕的!
微信提供了底层网络驱动以及成功和失败的回调.但对于一个项目中的实际使用而言,仍然还是显得繁琐,还有很多封装和简化的空间.
wx.request({
url: 'test.php',//请求的url
data: {//请求的参数
x: '' ,
y: ''
},
header: {//请求头
'Content-Type': 'application/json'
},
method:"POST",
success: function(res) {//成功的回调
console.log(res.data)
}
})
对于一个网络访问来说,请求一般是get和post,拼上各种参数以及请求头,然后拿到回来的响应,解析并得到最终需要的数据.
对于具体项目来说,请求时会有每个(或大多数)请求都要带的参数,都要带的请求头,返回的数据格式可能都是一致的,那么基于此,对微信的网络请求api进行二次封装:
在我目前的项目中,
大多数请求是post,基本上每个请求都需要携带sessionId来与服务器验证登录状态,还有很多请求是基于分页的,需要带上pageSize和pageIndex.
再跟页面逻辑关联起来,请求可能是因为第一次进入页面,或者刷新,或者上拉加载更多.
大多数拿到的数据格式是标准json格式,如下
{
"code":1,
"data":xxx,//可能是String,也可能是JsonObject,或JsonArray,也可能是null,或undefined
"msg":yyy//可能为空
}
通过请求的状态码code来判断这个请求是否真正成功.我们的项目中还有常见的是code=5:登录过期或未登录,code=2: 没有找到对应的内容 等等.
如果是大多数情况的请求时,只需要指定:
对于响应,我们只需要:
我们期望的api是:
netUtil.buildRequest(page,urlTail,params,callback)//必须的参数和回调 .setXxx(xxx)//额外的设置,链式调用 .. .send();//最终发出请求的动作
//这两个错误码是项目接口文档统一定义好的
const code_unlogin = 5;
const code_unfound = 2;
function requestConfig(){
this.page; //页面对象
this.isNewApi = true;
this.urlTail='';
this.params={
pageIndex:0,
pageSize:getApp().globalData.defaultPageSize,
session_id:getApp().globalData.session_id
};
this.netMethod='POST';
this.callback={
onPre: function(){},
onEnd: function(){
},
onSuccess:function (data){},
onEmpty : function(){},
onError : function(msgCanShow,code,hiddenMsg){},
onUnlogin: function(){
this.onError("您还没有登录或登录已过期,请登录",5,'')
},
onUnFound: function(){
this.onError("您要的内容没有找到",2,'')
}
};
this.setMethodGet = function(){
this.netMethod = 'GET';
return this;
}
this.setApiOld = function(){
this.isNewApi = false;
return this;
}
this.send = function(){
request(this);
}
}
//todo 拷贝这段代码去用--buildRequest里的callback
/*
onPre: function(){},
onEnd: function(){
hideLoadingDialog(page);
},
onSuccess:function (data){},
onEmpty : function(){},
onError : function(msgCanShow,code,hiddenMsg){},
onUnlogin: function(){
this.onError("您还没有登录或登录已过期,请登录",5,'')
},
onUnFound: function(){
this.onError("您要的内容没有找到",2,'')
}
* */
/**
* 注意,此方法调用后还要调用.send()才是发送出去.
* @param page
* @param urlTail
* @param params
* @param callback 拷贝上方注释区的代码使用
* @returns {requestConfig}
*/
function buildRequest(page,urlTail,params,callback){
var config = new requestConfig();
config.page = page;
config.urlTail = urlTail;
if (getApp().globalData.session_id == null || getApp().globalData.session_id == ''){
params.session_id=''
}else {
params.session_id = getApp().globalData.session_id;
}
if (params.pageIndex == undefined || params.pageIndex <=0 || params.pageSize == 0){
params.pageSize=0
}else {
if (params.pageSize == undefined){
params.pageSize = getApp().globalData.defaultPageSize;
}
}
log(params)
config.params = params;
log(config.params)
//config.callback = callback;
if(isFunction(callback.onPre)){
config.callback.onPre=callback.onPre;
}
if(isFunction(callback.onEnd)){
config.callback.onEnd=callback.onEnd;
}
if(isFunction(callback.onEmpty)){
config.callback.onEmpty=callback.onEmpty;
}
if(isFunction(callback.onSuccess)){
config.callback.onSuccess=callback.onSuccess;
}
if(isFunction(callback.onError)){
config.callback.onError=callback.onError;
}
if(isFunction(callback.onUnlogin)){
config.callback.onUnlogin=callback.onUnlogin;
}
if(isFunction(callback.onUnFound)){
config.callback.onUnFound=callback.onUnFound;
}
return config;
}
function request(requestConfig){
//检验三个公有参数并处理.这里与上面有所重复,是为了兼容之前写的几个api,不想改了.
requestConfig.params.sessionId= getApp().globalData.sessionId;
if (requestConfig.params.sessionId ==null || requestConfig.params.sessionId == ''){
delete requestConfig.params.sessionId;
}
if (requestConfig.params.pageIndex ==0 || requestConfig.params.pageSize == 0){
delete requestConfig.params.pageIndex ;
delete requestConfig.params.pageSize;
}
//var body = getStr("&", requestConfig.params);//拼接请求参数
requestConfig.onPre();//请求发出前
wx.request({
// url: getApp().globalData.apiHeadUrl+requestConfig.urlTail+"?"+body,貌似这样写,同时不给data赋值,post请求也是可以成功的
url: getApp().globalData.apiHeadUrl+requestConfig.urlTail,
method:requestConfig.netMethod,
data:requestConfig.params,
header: {'Content-Type':'application/json'},
success: function(res) {
console.log(res);
if(res.statusCode = 200){
var responseData = res.data
var code = responseData.code;
var msg = responseData.message;
if(code == 0){
var data = responseData.data;
var isDataNull = isOptStrNull(data);
if(isDataNull){
requestConfig.onEmpty();
}else{
requestConfig.onSuccess(data);
}
}else if(code == 2){
requestConfig.onUnFound();
}else if(code == 5){
requestConfig.onUnlogin();
}else{
var isMsgNull = isOptStrNull(msg);
if(isMsgNull){
var isCodeNull = isOptStrNull(code);
if (isCodeNull){
requestConfig.onError("数据异常!,请核查",code,'');
}else {
requestConfig.onError("数据异常!,错误码为"+code,code,'');
}
}else{
requestConfig.onError(msg,code,'');
}
}
}else if(res.statusCode >= 500){
requestConfig.onError("服务器异常!",res.statusCode,'');
}else if(res.statusCode >= 400 && res.statusCode < 500){
requestConfig.onError("没有找到内容",res.statusCode,'');
}else{
requestConfig.onError("网络请求异常!",res.statusCode,'');
}
},
fail:function(res){
console.log("fail",res)
requestConfig.onError("网络请求异常!",res.statusCode,'');
},
complete:function(res){
// that.setData({hidden:true,toast:true});
}
})
}
方法写在netUtil.js下,在该js文件最下方暴露方法:
module.exports = {
buildRequest:buildRequest
}
实际引用:
var netUtil=require("../../utils/netUtil.js");
小技巧: js无法像java一样定义好了接口,然后IDE自动生成代码.可以这样: 将callback的空方法写到netUtil的buildRequest方法上方的注释区,每次用时,点击方法名跳到那边去拷贝即可.
var params = {};
params.id = id;
netUtil.buildRequest(that,API.Album.DETAIL,params,{
onPre: function(){
netUtil.showLoadingDialog(that);
},
onEnd:function(){
},
onSuccess:function (data){
netUtil.showContent(that);
....
},
onEmpty : function(){
},
onError : function(msgCanShow,code,hiddenMsg){
netUtil.showErrorPage(that,msgCanShow);
},
onUnlogin: function(){
this.onError("您还没有登录或登录已过期,请登录",5,'')
},
onUnFound: function(){
this.onError("您要的内容没有找到",2,'')
}
}).send();
参考微信文档中ui设计规范,上拉加载更多的ui提示应该放在页面最下部占一行,而不应该在页面中间显示一个大大的loading的效果.
通过上面的分析,可以确定大部分页面的通用状态管理逻辑,那么就可以设计通用的状态管理模板了.
ui的显示是通过Page里的data中的数据来控制的,并通过page.setData({xxx})来刷新的,原先每个页面都拷贝同样的js属性和wxml代码去实现封装,后来进行了封装,js属性用方法来封装,通过微信提供的template封装共同的wxml代码,通过import或include导入到wxml中(但是不知什么bug,template一直无法起作用).
function netStateBean(){
//toast的是老api,工具升级后无需设置了
this.toastHidden=true,
this.toastMsg='',
this.loadingHidden=false,
this.emptyHidden = true,
this.emptyMsg='暂时没有内容,去别处逛逛吧',
this.errorMsg='',
this.errorHidden=true,
this.loadmoreMsg='加载中...',
this.loadmoreHidden=true,
}
Page(
data: {
title:'名师',//todo 设置标题栏
emptyMsg:'暂时没有内容,去别处逛逛吧',//todo 空白页面的显示内容
netStateBean: new netUtil.netStateBean(),
...
},
...
)
<template name="pagestate" >
<view class ="empty_view" wx: