仿洗衣小程序开发经验分享

解决问题,方便生活,为大学校园中,企业园区里洗衣服还要办理洗衣卡,洗衣服的时候还得揣着一张洗衣卡,只需要拿着手机扫一扫就能完美解决,畅洗洗衣微信小程序。下来看看该小程序“畅洗”,本人写了几个自己觉得主要的功能,还有部分功能待编写中,欢迎各位看官批评,同时跪求各位看官收藏点赞,不胜感激,上效果图:


概览.gif

注:PC端无法实现扫码,弹出打开文件框

一、准备工作

小程序吗,慢慢玩儿,微信给玩家提供了一大推你所需要的各种各种,你只要一个微信号就行。在开发小程序时,对小程序有个大概的认识就行,不求多牛逼,记得我心目中的大佬说过,不要发等你好牛逼了才来做牛逼的事,慢慢做,碰到问题解决问题,你就能牛逼起来,一台PC,同时匹配PC下载好微信小程序的开发者工具,编辑器,有很多种,本人用的VSCode,接下来就开始干了。

二、前期开发工作

打开微信公众平台网页见地址:https://mp.weixin.qq.com/,实名注册一个,扫码登录微信公众平台,点击设置->开发设置拿到属于自己的专属AppID(小程序ID),详见下图:

小程序ID.png

复制该AppID(小程序ID)至微信开发者工具,取名、选定文件夹 -> 添加项目,得到的页面又是这样的:
Hello World.png

单击左上角编辑,出现如下界面:
tree.png

pages文件夹下存放着小程序所有的业务功能实现页面,一般默认有俩,分别为index和logs;
index文件夹就是一个页面,index.wxml是页面的结构文件,类似html。
index.wxss是页面的样式,其实就是css;
index.js是页面的逻辑,数据请求与渲染都是都在这个页面完成。
logs文件夹存放着小程序开发日志,目前暂时用不到。
utils.js可以编写自己的JavaScript插件。
app.js处理全局的一些逻辑,比如定义全局变量存放获取的用户信息,这样每个页面都可以获取用户信息。
app.json 是全局配置文件,比如设置标题栏的背景色等。
app.wxss 存放页面的公共样式,如果多个页面需要用到同一样式,就可以写在这里。
项目按钮显示预览二维码,用于真机调试。必须真机调试测试代码
更加详细的文档参见:
https://mp.weixin.qq.com/debug/wxadoc/dev/framework/config.html?t=20161230
还有微信ui库的地址:https://weui.io/

三、分析业务创建所需页面结构

1、首先分析我们做的小程序有哪些需要用到的业务,创建相应的page,即在app.json文件里添加相应的代码,下图是我的.json页面:


myjson.png

创建了相应的page,同时删除了原有的Index和logs。
2、编写相应的通用样式,在app.wxss文件里编写,我就啥也没写,还注释了里面的代码。
3、经过上述第一步搭建好了页面结构,同事一样,上波图,更直观:


mytree.png

四、页面设计效果

1、首页大图,也是标志性的Logo(logo文件夹)


logo.gif

该页面跳转设计了点击跳转和定时跳转两种跳转方式,点击跳转可能.gif文件展示的不是很好
logo.js代码:

 bindLogoTap: function() {
    wx.navigateTo({
      url: '../iconInformation/iconInformation'
    })
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    // 设置初始计时秒数
    let time = 2;
    // 开始定时器
    this.timer = setInterval(() => {
      this.setData({
        time: -- time
      });
      // 读完秒后携带洗衣机编号跳转到计费页
      if(time < 0){
        clearInterval(this.timer)
        wx.navigateTo({
          url: '../iconInformation/iconInformation'
        })
      }
    },1000)
   
  },

logo.wxml代码:

<view class="logo">
  <image bindtap="bindLogoTap" class="logo_page" src="/images/logo.jpg" mode="widthFix"></image>
</view>

样式代码就不贴了,就用图片充满屏幕就行了。
2、主要处理页面,也是坑的我最惨的,一个抽屉栏我就半天出不来自己想要的效果,后找了猛人帮忙,搞定了,在此感谢,见下图:


抽屉.gif

.js代码如下,轻松愉快的一个自定义函数搞定,不想我之前的绕绕绕,然后我自己都不知道了

Page({
    data: {
        translate: '',
        showPageBottom: false
    },

    
    showMenu: function() {
        this.setData({
            showPageBottom: !this.data.showPageBottom
        })
    },
}

.wxml代码如下,图片绑定事件

<view class="page-bottom {{showPageBottom?'active':''}}">

3、业务界面,这里面设计的业务不是很多,就一张一张图片贴了。

3.1、点击信息小图标,进入到sms业务界面,图片如下:


消息.png

3.2、用户信息页,抽屉栏最上方小型logo图标出现,如下图:


用户信息.gif

部分js代码如下,单选按钮默认选中“男”
data: {
    items: [
      {name: 'men', value: '男', checked: 'true'},
      {name: 'women', value: '女'},
    ]
  },
  radioChange: function(e) {
    console.log('radio发生change事件,携带value值为:', e.detail.value)
  },

3.3、我的钱包页,点击我的钱包就好了,页面跳转后又有如果不选定金额,下面的提交按钮默认是灰色的,这是点击提交按钮出现的用户反馈信息弹窗;同时点击按钮的时候就提交按钮就变色显示,可选择充值金额,效果图如下:


我的钱包.gif

部分js代码如下:

// pages/wallet/wallet.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
      // 充值数额类型数组
    checkboxValue: [],
    // 提交按钮的背景色,未勾选类型时无颜色
    btnBgc: "",
    // 复选框的value,此处预定义,然后循环渲染到页面
    itemsValue: [
      {
        checked: false,
        value: "充值¥10轻币",
        color: "#b9dd08"
      },
      {
        checked: false,
        value: "充值¥20轻币",
        color: "#b9dd08"
      },
      {
        checked: false,
        value: "充值¥50轻币",
        color: "#b9dd08"
      },
      {
        checked: false,
        value: "充值¥60轻币",
        color: "#b9dd08"
      },
      {
        checked: false,
        value: "充值¥80轻币",
        color: "#b9dd08"
      },
      {
        checked: false,
        value: "充值¥100轻币",
        color: "#b9dd08"
      }
    ]
  },

  /**
   * 生命周期函数--监听页面加载
   */
  // 页面加载
  onLoad:function(options){
    wx.setNavigationBarTitle({
      title: '我的钱包'
    })
  },
// 勾选充值金额,获取类型值存入checkboxValue
  checkboxChange: function(e){
    let _values = e.detail.value;
    if(_values.length == 0){
      this.setData({
        btnBgc: ""
      })
    }else{
      this.setData({
        checkboxValue: _values,
        btnBgc: "#b9dd08"
      })
    }   
  },
// 输入充值金额,存入inputValue
  numberChange: function(e){
    this.setData({
      inputValue: {
        num: e.detail.value,
        desc: this.data.inputValue.desc
      }
    })
  },
// 输入备注,存入inputValue
  descChange: function(e){
    this.setData({
      inputValue: {
        num: this.data.inputValue.num,
        desc: e.detail.value
      }
    })
  },
// 提交到服务器
  formSubmit: function(e){
    if(this.data.checkboxValue.length> 0){
      wx.request({
        url: 'https://www.easy-mock.com/mock/59098d007a878d73716e966f/ofodata/msg',
        data: {
        },
        method: 'get', 
        success: function(res){
          wx.showToast({
            title: res.data.data.msg,
            icon: 'success',
            duration: 2000
          })
        }
      })
    }else{
      wx.showModal({
        title: "请填写反馈信息",
        content: '你宝贵的意见是我们改进的方向',
        confirmText: "如实填写",
        cancelText: "忽略",
        success: (res) => {
          if(res.confirm){
            // 继续填
          }else{
            console.log("back")
            wx.navigateBack({
              delta: 1 // 回退前 delta(默认为1) 页面
            })
          }
        }
      })
    }   
  }
})

3.4、优惠券页,效果图如下:


优惠券.gif

3.5、我的洗衣机页,查看当前已绑定的洗衣机,还可申请绑定或是租赁相应的洗衣机,效果图如下:


我的洗衣机.png

3.6、设置页,相关设置均在此,上效果图吧,如下:
设置.png

3.7、推荐给好友,这一页来点不同的,就写模块待开发


推荐给好友.gif

3.8、点我洗衣,主页面下方点我洗衣,效果图如下:
logo.png
点我洗衣.gif
扫码.jpg

拖动位置点击重新定位回到当前位置,另由于PC端扫码功能更不一样为打开文件形式,上的真机测试截图。貌似有点不伦不类,还请各位看官见谅。。。
js代码

//myoption.js
//获取应用实例
var app = getApp()
Page({
  data: {
    scale: 18,
    latitude: 22.650529,
    longitude: 113.925354
  },
// 页面加载
  onLoad: function (options) {
    // 1.获取定时器,用于判断是否在洗衣
    this.timer = options.timer;

    // 2.获取并设置当前位置经纬度定位
    wx.getLocation({
      type: "gcj02",
      success: (res) => {
        this.setData({
          longitude: res.longitude,
          latitude: res.latitude
        })
      }
    });

    // 3.设置地图控件的位置及大小,通过设备宽高定位
    wx.getSystemInfo({
      success: (res) => {
        this.setData({
          controls: [{
            id: 1,
            iconPath: '/images/location.png',
            position: {
            left: 20,
            top: res.windowHeight - 80,
            width: 50,
            height: 50
            },
            clickable: true
          },
          {
            id: 2,
            iconPath: '/images/use.png',
            position: {
            left: res.windowWidth/2 - 45,
            top: res.windowHeight - 100,
            width: 90,
            height: 90
            },
            clickable: true
          },
          {
            id: 3,
            iconPath: '/images/warn.png',
            position: {
            left: res.windowWidth - 70,
            top: res.windowHeight - 80,
            width: 50,
            height: 50
            },
            clickable: true
          },
          {
            id: 4,
            iconPath: '/images/marker.png',
            position: {
            left: res.windowWidth/2 - 11,
            top: res.windowHeight/2 - 45,
            width: 22,
            height: 45
            },
            clickable: true
          },
          {
            id: 5,
            iconPath: '/images/avatar.png',
            position: {
            left: res.windowWidth - 68,
            top: res.windowHeight - 155,
            width: 45,
            height: 45
            },
            clickable: true
          }]
        })
      }
    });

    // 4.请求服务器,显示附近的洗衣机,用marker标记
    wx.request({
      url: 'http://easy-mock.com/mock/596d6dbea1d30433d835cab0/query/list',
      data: {},
      method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
      // header: {}, // 设置请求的 header
      success: (res) => {
          this.setData({
            markers: res.data.data
          })
      },
      fail: function(res) {
        // fail
      },
      complete: function(res) {
        // complete
      }
    })
  },
// 页面显示
  onShow: function(){
    // 1.创建地图上下文,移动当前位置到地图中心
    this.mapCtx = wx.createMapContext("QingKeMap");
    this.movetoPosition()
  },
// 地图控件点击事件
  bindcontroltap: function(e){
    // 判断点击的是哪个控件 e.controlId代表控件的id,在页面加载时的第3步设置的id
    switch(e.controlId){
      // 点击定位控件
      case 1: this.movetoPosition();
        break;
      // 点击立即洗衣,判断当前是否正在计时
      case 2: if(this.timer === "" || this.timer === undefined){
          // 没有在计费就扫码
          wx.scanCode({
            success: (res) => {
              // 正在获取密码通知
              wx.showLoading({
                title: '洗衣准备',
                mask: true
              })
              // 请求服务器获取密码和洗衣机
              wx.request({
                url: 'http://easy-mock.com/project/596d6dbea1d30433d835cab0/query',
                data: {},
                method: 'GET', 
                success: function(res){
                  // 请求密码成功隐藏等待框
                  wx.hideLoading();
                  // 携带密码和洗衣机编号跳转到密码页
                  wx.redirectTo({
                    url: '../scanresult/index?password=' + res.data.data.password + '&number=' + res.data.data.number,
                    success: function(res){
                      wx.showToast({
                        title: '获取密码成功',
                        duration: 1000
                      })
                    }
                  })           
                }
              })
            }
          })
        // 当前已经在计费就回退到计费页
        }else{
          wx.navigateBack({
            delta: 1
          })
        }  
        break;
      default: break;
    }
  },
// 地图视野改变事件
  bindregionchange: function(e){
    // 拖动地图,获取附件洗衣机位置
    if(e.type == "begin"){
      wx.request({
        url: 'http://easy-mock.com/mock/596d6dbea1d30433d835cab0/query/list',
        data: {},
        method: 'GET', 
        success: (res) => {
          this.setData({
            _markers: res.data.data
          })
        }
      })
    // 停止拖动,显示单车位置
    }else if(e.type == "end"){
        this.setData({
          markers: this.data._markers
        })
    }
  },
// 地图标记点击事件,连接用户位置和点击的单车位置
  bindmarkertap: function(e){
    console.log(e);
    let _markers = this.data.markers;
    let markerId = e.markerId;
    let currMaker = _markers[markerId];
    this.setData({
      polyline: [{
        points: [{
          longitude: this.data.longitude,
          latitude: this.data.latitude
        }, {
          longitude: currMaker.longitude,
          latitude: currMaker.latitude
        }],
        color:"#FF0000DD",
        width: 1,
        dottedLine: true
      }],
      scale: 18
    })
  },
// 定位函数,移动位置到地图中心
  movetoPosition: function(){
    this.mapCtx.moveToLocation();
  }
})

wxml文件

<view class="container">
  <map id="QingKeMap" latitude="{{latitude}}" longitude="{{longitude}}" scale="{{scale}}" bindregionchange="bindregionchange" polyline="{{polyline}}" markers="{{markers}}" controls="{{controls}}" bindmarkertap="bindmarkertap"  bindcontroltap="bindcontroltap" show-location/>
</view>

五、扩展总结

由于服务器和本人技术问题,这里免得数据使用的是easy-mock伪造数据;easy-mock可以作为前端开发的伪后端,自己构造数据来测试前端代码。方便又快捷。官网戳这里
同时使用了一些微信小程序的官方API,如:
扫码API: wx.scanCode({})
向服务器发送请求:wx.request({})
显示加载框: wx.showLoading()
隐藏加载框: wx.hideLoading()
显示提示框: wx.showToast()
隐藏提示框: wx.hideToast()
关闭当前页面,跳转到指定页面: wx.redirectTo({})
保留当前页面,跳转到指定页面: wx.navigateTo({})
回退到指定页面: wx.naivgateBack({})
一些详细用法和更多其他的API请查看微信小程序API文档
小结:畅洗洗衣下程序也弄得七七八八了,剩下还有一些功能待接下来继续完成,本人开发过程中遇到过很多的坎,有一个个人觉得最重要的效果显示(抽屉栏菜单)好久都没有做出自己的想要的效果,查了N多资料,就是搞不定,最后请教大佬实例操作一波,几行子代码替代我几十行代码搞定,最重要的是我的几十行还实现不了,这就很尴尬了吧,咸鱼还是得努力翻身啊!不会的找大神,提点几句自己动手做能解决最好了,实在不行,请教大佬实地地操作一波了,搞定了自己还得好好悟,努力进步就是最好的。在此跪求各位看官不吝啬点点手指的力气去,点点手指,收藏,点赞,喜欢能来的就来一波,小的跪求。。。。。。
同时源码在小的的github上,有需要的欢迎fork
附注:本人求职中,坐标深圳,同时不介意北上广杭等互联网发展聚集地,
联系方式:电话:18770919203 邮箱:1412453932@qq.com/18770919203@163.com
欢迎骚扰!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,265评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,274评论 1 288
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,087评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,479评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,782评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,218评论 1 207
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,594评论 2 309
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,316评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,955评论 1 237
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,274评论 2 240
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,803评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,177评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,732评论 3 229
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,953评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,687评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,263评论 2 267
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,189评论 2 258

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,535评论 25 707
  • 给提问的开发者的建议:提问之前先查询 文档、通过社区右上角搜索搜索已经存在的问题。 写一个简明扼要的标题,并且...
    极乐叔阅读 13,099评论 0 3
  • 至于为什么做小程序的文档教程,原因有以下几点 小程序在1月9号正式对外公测,业界大佬们纷纷入驻小程序,当天就推出小...
    DanD丶榆木稚年阅读 1,897评论 3 8
  • By栏目主持喵姐 她蜜:吉林子 从毕业到现在,我换了快十份工作 她她,我也想把我的情况跟大家说说,我不明白自己到底...
    她生活阅读 1,162评论 1 3
  • 这个月由于赶毕设等个人原因,导致只读了六本书,比上个月少很多。 相关评论简述如下: 《挪威的森林》 四星 这是我看...
    流噪阅读 265评论 0 1