微信小程序开发:ES6异步请求接口及封装实例
小程序项目根目录
1、 pages[home]
2、 utils[base.js,config.js]
3、 其中home文件夹包含[home.js,home.json,home.wxml,home.wxss, home-model.js]
文件内容:
home.js
import { Home } from 'home-model.js';
var home = new Home(); //实例化 首页 对象
Page({
data: {
loadingHidden: false
},
onLoad: function () {
this._loadData();
},
/*加载所有数据*/
_loadData:function(callback){
var that = this;
// 获得bannar信息
home.getBannerData((data) => {
that.setData({
bannerArr: data,
});
});
/*获取主题信息*/
home.getThemeData((data) => {
that.setData({
themeArr: data,
loadingHidden: true
});
});
/*获取单品信息*/
home.getProductorData((data) => {
that.setData({
productsArr: data
});
callback&&callback();
});
},
/*跳转到商品详情*/
onProductsItemTap: function (event) {
var id = home.getDataSet(event, 'id');
wx.navigateTo({
url: '../product/product?id=' + id
})
},
/*跳转到主题列表*/
onThemesItemTap: function (event) {
var id = home.getDataSet(event, 'id');
var name = home.getDataSet(event, 'name');
wx.navigateTo({
url: '../theme/theme?id=' + id+'&name='+ name
})
},
/*下拉刷新页面*/
onPullDownRefresh: function(){
this._loadData(()=>{
wx.stopPullDownRefresh()
});
},
//分享效果
onShareAppMessage: function () {
return {
title: '零食商贩',
path: 'pages/home/home'
}
}
})
home-model.js
/**
* Created by jimmy on 17/2/26.
*/
// var Base = require('../../utils/base.js').base;
import {Base} from '../../utils/base.js';
class Home extends Base{
constructor(){
super();
}
/*banner图片信息*/
getBannerData(callback){
var that=this;
var param={
url: 'banner/1',
sCallback:function(data){
data=data.items;
callback && callback(data);
}
};
this.request(param);
}
/*首页主题*/
getThemeData(callback){
var param={
url: 'theme?ids=1,2,3',
sCallback:function(data){
callback && callback(data);
}
};
this.request(param);
}
/*首页部分商品*/
getProductorData(callback){
var param={
url: 'product/recent',
sCallback:function(data){
callback && callback(data);
}
};
this.request(param);
}
};
export {Home};
home.wxml
<import src="../tpls/products/products-tpl.wxml"/>
<view class="container home-container" hidden="{{!loadingHidden}}">
<swiper indicator-dots="true" autoplay="true" class="swiper">
<block wx:for="{{bannerArr}}">
<swiper-item class="banner-item" bindtap="onProductsItemTap" data-id="{{item.key_word}}">
<image class="item-image" src="{{item.img.url}}" mode="aspectFill" />
</swiper-item>
</block>
</swiper>
<view class="home-main">
<!--主题精选-->
<view class="home-main-theme">
<view class="home-main-header">精选主题</view>
<view class="theme-box">
<block wx:for="{{themeArr}}">
<view wx:if="{{index==2}}" class="theme-item big" bindtap="onThemesItemTap" data-id="{{item.id}}" data-name="{{item.name}}">
<image src="{{item.topic_img.url}}"></image>
</view>
<view wx:else class="theme-item" bindtap="onThemesItemTap" data-id="{{item.id}}" data-name="{{item.name}}">
<image src="{{item.topic_img.url}}"></image>
</view>
</block>
</view>
</view>
<!--单品首发-->
<view class="home-main-products">
<view class="home-main-header">最近新品</view>
<template is="products" data="{{productsArr:productsArr}}"/>
</view>
</view>
</view>
<loading hidden="{{loadingHidden}}">
加载中...
</loading>
tpls/products/products-tpl.wxml
<template name="products">
<view class="products-box">
<block wx:for="{{productsArr}}">
<view class="products-item" bindtap="onProductsItemTap" data-id="{{item.id}}">
<image class="products-image" src="{{item.main_img_url}}" mode="aspectFill"></image>
<view class="products-item-bottom">
<text class="name">{{item.name}}</text>
<view class="price">¥{{item.price}}</view>
</view>
</view>
</block>
</view>
</template>
base.js
/**
* Created by jimmy-jiang on 2016/11/21.
*/
import { Token } from 'token.js';
import { Config } from 'config.js';
class Base {
constructor() {
"use strict";
this.baseRestUrl = Config.restUrl;
this.onPay=Config.onPay;
}
//http 请求类, 当noRefech为true时,不做未授权重试机制
request(params, noRefetch) {
var that = this,
url=this.baseRestUrl + params.url;
if(!params.type){
params.type='get';
}
/*不需要再次组装地址*/
if(params.setUpUrl==false){
url = params.url;
}
wx.request({
url: url,
data: params.data,
method:params.type,
header: {
'content-type': 'application/json',
'token': wx.getStorageSync('token')
},
success: function (res) {
// 判断以2(2xx)开头的状态码为正确
// 异常不要返回到回调中,就在request中处理,记录日志并showToast一个统一的错误即可
var code = res.statusCode.toString();
var startChar = code.charAt(0);
if (startChar == '2') {
params.sCallback && params.sCallback(res.data);
} else {
if (code == '401') {
if (!noRefetch) {
that._refetch(params);
}
}
that._processError(res);
params.eCallback && params.eCallback(res.data);
}
},
fail: function (err) {
//wx.hideNavigationBarLoading();
that._processError(err);
// params.eCallback && params.eCallback(err);
}
});
}
_processError(err){
console.log(err);
}
_refetch(param) {
var token = new Token();
token.getTokenFromServer((token) => {
this.request(param, true);
});
}
/*获得元素上的绑定的值*/
getDataSet(event, key) {
return event.currentTarget.dataset[key];
};
};
export {Base};
config.js
class Config{
constructor(){
}
}
Config.restUrl = 'REST API 基地址';
Config.onPay=true; //是否启用支付
export {Config};
token.js
// 引用使用es6的module引入和定义
// 全局变量以g_开头
// 私有函数以_开头
import { Config } from 'config.js';
class Token {
constructor() {
this.verifyUrl = Config.restUrl + 'token/verify';
this.tokenUrl = Config.restUrl + 'token/user';
}
verify() {
var token = wx.getStorageSync('token');
if (!token) {
this.getTokenFromServer();
}
else {
this._veirfyFromServer(token);
}
}
_veirfyFromServer(token) {
var that = this;
wx.request({
url: that.verifyUrl,
method: 'POST',
data: {
token: token
},
success: function (res) {
var valid = res.data.isValid;
if(!valid){
that.getTokenFromServer();
}
}
})
}
getTokenFromServer(callBack) {
var that = this;
wx.login({
success: function (res) {
wx.request({
url: that.tokenUrl,
method:'POST',
data:{
code:res.code
},
success:function(res){
wx.setStorageSync('token', res.data.token);
callBack&&callBack(res.data.token);
}
})
}
})
}
}
export {Token};
address.js
/**
* Created by jimmy on 17/3/9.
*/
import {Base} from 'base.js';
import { Config } from 'config.js';
class Address extends Base{
constructor() {
super();
}
/*获得我自己的收货地址*/
getAddress(callback){
var that=this;
var param={
url: 'address',
sCallback:function(res){
if(res) {
res.totalDetail = that.setAddressInfo(res);
callback && callback(res);
}
}
};
this.request(param);
}
/*保存地址*/
_setUpAddress(res,callback){
var formData={
name:res.userName,
province:res.provinceName,
city:res.cityName,
country:res.countyName,
mobile:res.telNumber,
detail:res.detailInfo
};
return formData;
}
/*更新保存地址*/
submitAddress(data,callback){
data = this._setUpAddress(data);
var param={
url: 'address',
type:'post',
data:data,
sCallback:function(res){
callback && callback(true,res);
},eCallback(res){
callback && callback(false,res);
}
};
this.request(param);
}
/*是否为直辖市*/
isCenterCity(name) {
var centerCitys=['北京市','天津市','上海市','重庆市'],
flag=centerCitys.indexOf(name) >= 0;
return flag;
}
/*
*根据省市县信息组装地址信息
* provinceName , province 前者为 微信选择控件返回结果,后者为查询地址时,自己服务器后台返回结果
*/
setAddressInfo(res){
var province =res.provinceName || res.province,
city =res.cityName || res.city,
country =res.countyName || res.country,
detail =res.detailInfo || res.detail;
var totalDetail=city+country+detail;
console.log(res);
//直辖市,取出省部分
if(!this.isCenterCity(province)) {
totalDetail=province+totalDetail;
};
return totalDetail;
}
}
export {Address}