微信小程序开发日志——面向对象的JS编程

微信小程序开发日志——面向对象的JS编程

前言

不知道有多少小伙伴和之前的我一样,微信小程序的js部分都是用面向过程的方式写的,最后的结果就是代码非常长,其实刚刚写完还好,自己也都清楚哪些部分是做什么的,但是当自己回过头来看时,就发现看的有点吃力了,而且代码非常长,看完所有的代码非常吃力,还有一个就是面向过程的代码中,以访问后台数据为例,我们通常要经常调用wx.request,这个API的复用率是非常高的,同时url每次都得重新写,如果哪天我们更改了url那么岂不是都得要重新改,所以如果全是面向过程的思想写的代码,那么效率是非常低的。

如我之前写的代码:

const app = getApp()
var tt = require('../../utils/util.js');
Page({

  /**
   * 页面的初始数据
   */
  data: {
    ordername:"",
    time: "",
    click:"",
    orderimg:[],
    orderdetail:"",
    orderprice:"",
    orderperson:"",
    ordernumber:"",
    orderwechat:"",
    orderid:"",
    chatlist:"",
    content:"留下点什么吧....",
    replyuserid:null,
    iv:0,
    inputcontent:null,
    userimg: "",
    username: "",
    iscollected:null,
    orderlostposition:"",
    orderlosttime: "",
    sortthings: "",
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    wx.showLoading({
      title: '加载中',
      mask: 'true'
    })
    wx.setStorageSync('orderid', options.id)
    console.log(options)
    var _this=this
    var orderimg = _this.data.orderimg
    orderimg.push(options.orderimg0)
    orderimg.push(options.orderimg1)
    orderimg.push(options.orderimg2)
    console.log(orderimg)
    wx.removeStorage({
      key: 'replyuserid',
    })
    /*wx.setStorage({
      key: 'orderid',
      data: options.id
    })*/
 _this.setData({
      ordername : options.ordername,
      time: options.time,
      click: options.click,
   /*   orderimg0: options. orderimg0,
      orderimg1: options.orderimg1,
      orderimg2: options.orderimg2,*/
      orderdetail: options. orderdetail,
      orderprice: options. orderprice,
      orderperson: options. orderperson,
      ordernumber: options. ordernumber,
      orderwechat: options. orderwechat,
      orderid: options.id,
      orderimg: orderimg,
      username: options.username,
      userimg: options.userimg,
      orderlostposition: options.orderlostposition,
      orderlosttime: options.orderlosttime,
   sortthings: options.sortthings,
    })
    wx.request({
      url:  app.globalData.url+'/est/orderclick.php', // 仅为示例,并非真实的接口地址
      data: {
        orderid: options.id
      },
      method: "POST",
      header: {
        "Content-Type": "application/x-www-form-urlencoded" // 默认值
      },
      success(res) {
       
      }
    })
    wx.request({
      url: app.globalData.url +'/est/findcollected.php', // 仅为示例,并非真实的接口地址
      data: {
        orderid: wx.getStorageSync('orderid'),
        userid: wx.getStorageSync('userid'),
        collectedstatus: 0
      },
      method: "POST",
      header: {
        "Content-Type": "application/x-www-form-urlencoded" // 默认值
      },
      success(res) {
        console.log(res.data.collectedstatus)
        if (res.data.collectedstatus==1){
          _this.setData({
            iscollected:true
          })
        }
        else{
          _this.setData({
            iscollected:false
          })
        }
      }
    })
  
    wx.hideLoading()
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
    var _this=this
    var iv = _this.data.iv
    console.log("111")
    wx.getStorage({
      key: 'userid',
      success(res) {
        console.log(res.data)
        wx.request({
          url: app.globalData.url +'/est/userstatus.php', // 仅为示例,并非真实的接口地址
          data: {
            userid: wx.getStorageSync('userid')
          },
          method: "POST",
          header: {
            "Content-Type": "application/x-www-form-urlencoded" // 默认值
          },
          success(res) {
            console.log(res.data)
            _this.setData({
              iv: res.data.iv
            })
            iv = res.data.iv
            console.log(iv)
            wx.hideLoading()
            wx.showToast({ title: '加载成功!', duration: 1000 })
          },
          fail(){
            wx.hideLoading()
            wx.showToast({ title: '加载失败!', duration:1000 })
          }
        })
      },
      fail(res){   
        console.log(iv)
      }
    })
    
    var _this = this
    wx.request({
      url: app.globalData.url +'/est/chatlist.php', // 仅为示例,并非真实的接口地址
      data: {
        orderid: wx.getStorageSync('orderid')
      },
      method: "POST",
      header: {
        "Content-Type": "application/x-www-form-urlencoded" // 默认值
      },
      success(res) {
        console.log(res.data)
        _this.setData({
          chatlist: res.data
        })
      }
    })



  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
   

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  },
  formSubmit:function(e){
    wx.showLoading({
      title: '加载中',
      mask: 'true'
    })
    var _this = this
    var useid = wx.getStorageSync('userid')
    console.log(useid)
    
    if (e.detail.value.inputchat!=0){
      if (useid.length==0){
        wx.showToast({
          title: '请先登陆!',
          duration: 2000,
          icon: 'loading'
        })
        setTimeout(function () {
        
            wx.showModal({
              title: '提示',
              content: '是否跳转至授权登陆界面?',
              success(res) {
                if (res.confirm) {
                  wx.navigateTo({
                    url: '../user/user/log'
                  }) 
                } else if (res.cancel) {

                }
              }
            })
        
        }, 1000)
        
      }
      else
      {
        console.log("留言内容")
        console.log(e.detail.value.inputchat)
        var time = tt.formatTime(new Date())
        console.log("时间")
        console.log(time)
        var userid = wx.getStorageSync('userid')
        console.log("测试输出userid")
        console.log(userid)
        var userinfo = wx.getStorageSync('userInfo')
        console.log("userinfo.avatarUrl")
        console.log(userinfo.avatarUrl)
        var orderid = _this.data.orderid
        console.log("orderid")
        console.log(orderid)
        wx.request({
          url: app.globalData.url +'/est/pubchat.php', // 仅为示例,并非真实的接口地址
          data: {
            userimg: userinfo.avatarUrl,
            userid: wx.getStorageSync('userid'),
            time: time,
            content: e.detail.value.inputchat,
            orderid: orderid,
            username: userinfo.nickName,
            replyuserid: wx.getStorageSync('replyuserid'),
            replyopenid: wx.getStorageSync('userid'),
          },
          method: "POST",
          header: {
            "Content-Type": "application/x-www-form-urlencoded" // 默认值
          },
          success(res) {
            console.log(res.data)
            if (res.data.status == 1) {
              wx.showToast({ title: '留言成功!', duration: 500 })
                
              setTimeout(function () {
                wx.navigateBack({})
              }, 1000)
        
            } else {
              wx.showToast({
                title: '留言失败,请重试!',
                duration: 2000,
                  icon: 'loading'
              })
            }
          }
        })



      }
     
    }
    else{
      wx.showToast({
        title: '留言不能为空!',
        duration: 500,
        icon:'loading'

      })
    }



  },
  choicereply:function(e){
    var _this=this
    console.log(e.currentTarget.dataset.bean.username)
    _this.setData({
      content: "回复@"+e.currentTarget.dataset.bean.username
    })
    wx.setStorage({
      key: 'replyuserid',
      data: e.currentTarget.dataset.bean.username
    })

  },
  imgyu: function (e){
    console.log(e)
    var that = this,
      //获取当前图片的下表
      index = e.currentTarget.dataset.index,
      //数据源
      orderimg= this.data.orderimg;
    wx.previewImage({
      //当前显示下表
      current: orderimg[index],
      //数据源
      urls: orderimg
    })
  },
  sc:function(e){
    var useid = wx.getStorageSync('userid')
    if (useid.length == 0) {
      wx.showToast({
        title: '请先登陆!',
        duration: 2000,
        icon: 'loading'
      })
      setTimeout(function () {

        wx.showModal({
          title: '提示',
          content: '是否跳转至授权登陆界面?',
          success(res) {
            if (res.confirm) {
              wx.navigateTo({
                url: '../user/user/log'
              })
            } else if (res.cancel) {

            }
          }
        })

      }, 1000)

    }
    else {
    console.log(e)
    let iscollected = !this.data.iscollected
    this.setData({
      iscollected
    })
    if (iscollected){
      wx.request({
        url: app.globalData.url +'/est/changecollected.php', // 仅为示例,并非真实的接口地址
        data: {
          orderid: wx.getStorageSync('orderid'),
          userid: wx.getStorageSync('userid'),
          collectedstatus:1,
          sctime:tt.formatTime(new Date())
        },
        method: "POST",
        header: {
          "Content-Type": "application/x-www-form-urlencoded" // 默认值
        },
        success(res) {
          console.log(res.data)
        }
      })
    }else{
      wx.request({
        url: app.globalData.url +'/est/changecollected.php', // 仅为示例,并非真实的接口地址
        data: {
          orderid: wx.getStorageSync('orderid'),
          userid: wx.getStorageSync('userid'),
          collectedstatus: 0,
          sctime:tt.formatTime(new Date())
        },
        method: "POST",
        header: {
          "Content-Type": "application/x-www-form-urlencoded" // 默认值
        },
        success(res) {
          console.log(res.data)
        }
      })
    }
   
    this.onShow();
    console.log(iscollected)
    //提示用户
    wx.showToast({
      title: iscollected ? '收藏成功' : '取消收藏',
      icon: 'success',
      duration:1000,
    })
  }
  }
})

所以我们在这里模仿后端,用面向对象的编程思想来实现模块化的编码,实现代码的复用和模块分离,提高开发效率。

以request为例,微信小程序实现模型分类

首先我们先进行逻辑层的划分:

控制器层index.js:代码简单,非常容易读懂,基本上都是对业务逻辑层的调用。

业务逻辑层home-model.js:业务逻辑实现层,业务逻辑通过类方法来封装,继承于模型基类,使用基类的一些公用方法。

基类层Base.js:读取配置层,实现各种公用方法,供逻辑层调用

配置层Config.js:实现URL等等的配置

以下为代码详解(由底层向上):

类的定义(以配置层Config.js为例)

class Config{
  constructor(){

  }
}

Config.restUrl = 'http://www.csn.com/tp5/public/index.php/api/v1/'


export{Config}

Config.restUrl 可以理解为定义静态变量

class Config{
  constructor(){

  }
}
export{Config}

以上为类定义的基本结构,注意要用export来设置“接口”

类的引用(以Base.js为例)

import{Config} from '../utils/config.js';
class Base {
  constructor(){
      this.baseRequestUrl=Config.restUrl;
  }
  request(params){
    var url=this.baseRequestUrl+params.url;
    if(!params.type){
      params.type='GET';
    }
    wx.request({
      url: url,
      header:{
        'content-type':'application/json',
        'token':wx.getStorageSync('token')
      },
      success:function(res){
        params.sCallback && params.sCallback(res.data);
      }
    })
  }
}
export{Base}

我们使用

import{Config} from '../utils/config.js';

来引入类,同时在构造函数中定义变量this.baseRequestUrl=Config.restUrl;

在Base类中,我们定义request业务层公用方法,同时获得从业务层的参数params,在此方法中统一调用wx.request的API

类的继承(以业务逻辑层home-model.js为例)

import{Base} from '../../utils/Base.js'

class Home extends Base{
  constructor(){
      super();
  }
  getBannerData(id,callback){
    var params={
      url: 'banner?id='+id,
      sCallback:function(res){
        callback&&callback(res)
      }
    }
    this.request(params)
  }
}

export{Home};

注意,我们要在构造函数中用super();来引入父类

其次在此层中,我们根据业务逻辑定义方法,在方法中定义params,然后将params传入request方法中,也就是基类的方法,这样就可以向服务器请求数据。不再需要重复编写WX.request的API

类的实例化(以控制层index.js为例)

import { Home } from 'home-model.js';

var home=new Home();
Page({

  /**
   * 页面的初始数据
   */
  data: {
    
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this._onloadData();
  },
  _onloadData:function(){
    var id=1;
    var data = home.getBannerData(id,res=>{
      console.log(res)
    });
  },

})

此层是我们很熟悉的index.js文件,在此文件中,我们只需要引入业务逻辑层文件,然后实例化对象,就可以在index.js中调用业务逻辑层的getBannerData方法,所以此层的代码非常简洁明了。

回调函数

微信小程序的是异步执行的,所以我们得使用回调函数,具体请看
微信小程序的异步和回调函数

这里补充一点

 callback&&callback(res)

这条代码的意思是只有当callBack存在的时候,再执行callBack

总结

通过代码的分层,我们实现了代码功能的模块化,在控制器层的代码非常清楚明了,就是简单的几个方法调用,我们以后再看代码的时候,尽管忘记了细节,但是也能看懂大致的流程,而业务逻辑层更加专注业务方法的实现,

基类提供了各种公用的API,节省了API调用的重复,而配置层,则大大的减少了域名或或环境更改造成的影响。

你可能感兴趣的:(javascript,小程序)