0基础入门完成简单的“每天有乐”微信小程序(不含后台)


博客班级 https://edu.cnblogs.com/campus/zjcsxy/SE2020
作业要求 https://edu.cnblogs.com/campus/zjcsxy/SE2020/homework/11334
作业目标
  • 编写一个小程序,可以全新编写,也可以学习别人的小程序进行修改
  • 熟悉git代码管理流程,将源代码上传到到github
  • 在博客园班级中写一篇相应的博文
作业源代码 https://github.com/aiai0603/software-engineering-demo-1.git
学号/姓名 31801150/张帅
院系 浙大城市学院计算机系

 

  

  前言:软件工程课程的第一次作业,单独完成一个简单的微信小程序(不含后台),本文主要讲解如何从0基础入门来编写,含源代码和注解。本人纯小白,大佬勿喷,有错误请批评指正。

  最终作品地址:https://github.com/aiai0603/software-engineering-demo-1.git(仅供参考)

  开发工具:微信开发者工具

  效果演示

         

   (预览版)

  全局配置

  app.json:

  pages:配置微信的小程序的所有页面。第一项"pages/index/index"为默认显示的界面,本程序包含9个界面。

 1     "pages/index/index",      //个人信息首页
 2     "pages/logs/logs",        //奖券列表展示页
 3     "pages/main/main",        //主页
 4     "pages/rule/rule",        //积分规则
 5     "pages/policy/policy",    //隐私政策
 6     "pages/score/score",      //积分页面
 7     "pages/set/set",          //个人设置
 8     "pages/show/show",        //领券页面
 9     "pages/shop/shop"         //积分商店

  windows:全局配置页面效果,具体请参看官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/config.html

1   "window":{
2     "backgroundTextStyle":"dark",                      
3     "navigationBarBackgroundColor": "#f21515",
4     "navigationBarTitleText": "Happy everyday",
5     "navigationBarTextStyle":"black",
6     "enablePullDownRefresh": true
7   }, 

  tabbar:下方导航条配置,设置导航条的文字和图标

 1 "tabBar": {
 2     "selectedColor":  "#f21515",                //选中时文字颜色
 3     "list": [{
 4       "pagePath": "pages/main/main",            //跳转的页面
 5       "text": "首页",                            //文字
 6       "iconPath":"pages/1.jpg" ,                //未选中时显示的图表
 7       "selectedIconPath": "pages/1-1.jpg"       //选中时的图标
 8     },{
 9       "pagePath": "pages/logs/logs",
10       "text": "优惠券",
11       "iconPath":"pages/3.jpg" ,
12       "selectedIconPath": "pages/3-3.jpg"
13     },{
14       "pagePath": "pages/index/index",
15       "text": "我的",
16       "iconPath":"pages/2.jpg" ,
17       "selectedIconPath": "pages/2-2.jpg"
18     }]
19 }

    

    app.js:

    globalData:全局变量,用于存储数据,模拟变化。

 1 globalData: {
 2     userInfo: null,                            //个人信息
 3     disabled:false,                            //控制按钮是否可用
 4     color:"red",                               //控制按钮颜色
 5     pricenum:3,                                //控制持有券数
 6     price:[                                    //持有券的列表
 7       {
 8         available:0,                              //是否可用
 9         count:2,                                  //折扣
10         money:3,                                  //满多少可用
11         name:"雪碧满3减2券",                        //券名
12         day:"2020.1.1-2021.1.1可用"                //说明
13       }........(此处省略)
14     ],
15     score:[{                                       //积分信息
16           day:"2020/10/11 12:00:31",               //时间
17           title:"签到奖励",                         //说明
18           point:2                                  //获得积分数
19     }........(此处省略)],
20   scorenum:506,                                   //积分总数
21   sign:"签到",                                     //签到按钮文字
22   style:"qd"                                      //签到按钮样式名
23   },
24  

  分页代码

   在每一页的json文件中,设置好每一页的标题文字和颜色

1 {
2   "usingComponents": {},                        //使用组建(本dome未使用)
3   "navigationBarTitleText": "我的",              //标题文字
4   "navigationBarTextStyle":"white",             //标题颜色
5 }
  
  pages/index/index(主页):
  上半使用 wx:if/wx else 控制,如果未授权登录且条件支持则显示授权按钮,如果已经有授权信息则显示头像和微信名
       
  index.wxml
1 <view class="container">
2   <view class="userinfo">
3     <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo">授权登录 </button>
4     <block wx:else>
5       <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
6       <text class="userinfo-nickname">{{userInfo.nickName}}</text>
7 </block>
8 </view>

  index.js

 1 onLoad: function () {
 2     if (app.globalData.userInfo) {               //如果全局变量中已经存在授权信息则赋值给当前页面的变量
 3       this.setData({
 4         userInfo: app.globalData.userInfo,
 5         hasUserInfo: true
 6       })
 7     } else if (this.data.canIUse){
 8       // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
 9       // 所以此处加入 callback 以防止这种情况
10       app.userInfoReadyCallback = res => {
11         this.setData({
12           userInfo: res.userInfo,
13           hasUserInfo: true
14         })
15       }
16     } else {
17       // 在没有 open-type=getUserInfo 版本的兼容处理
18       wx.getUserInfo({
19         success: res => {
20           app.globalData.userInfo = res.userInfo
21           this.setData({
22             userInfo: res.userInfo,
23             hasUserInfo: true
24           })
25         }
26       })
27     }
28   },
29 
30   getUserInfo: function(e) {                               //获得授权的者的微信名
31     console.log(e)
32     app.globalData.userInfo = e.detail.userInfo
33     this.setData({
34       userInfo: e.detail.userInfo,
35       hasUserInfo: true
36     })
37   }

  下方为view标签编写的功能栏,使用navigator标签实现跳转到指定的页面

  PS:navigator标签只能跳转到非tabbar的页面,跳转到tabbar界面需要使用函数:

1  wx.switchTab({             //跳转至tabbar页面
2       url: '../logs/logs'
3   })
4 
5 <navigator url="../score/score">            //跳转到非tabbar界面   

  

  pages/logs/logs(优惠券的展示页面):

  要调用全局变量,需要在js文件开头写上调用语句

1 var app=getApp();

  将全局变量的值赋值给当前页面的变量,即可在当前页面使用

1  onShow: function () {
2     this.setData({
3       price:app.globalData.price
4   })

  头部使用选项卡检索“未使用”和“历史记录”的信息,绑定事件点击切换

      

  logs.wxml

 1 <view id='tabs'>
 2   <view class='tabs-box'>
 3     <block wx:for="{{['未使用','历史记录']}}" wx:key="index">
 4       <view class="tabs-item {{currentTabIndex == index ? 'selected' : '' }}" bindtap='onTabsItemTap' data-index='{{index}}'>
 5         {{item}}      
 6       </view>
 7     </block>
 8   </view>
 9   <view class='ordert-detail'>
10     <view hidden='{{currentTabIndex != 0}}'>(省略)
11     </view>
12     <view hidden='{{currentTabIndex != 1}}'>(省略)
13 </view> 14 </view>

  logs.js

1  onTabsItemTap:function(event){
2     let index=event.currentTarget.dataset.index;
3     this.setData({
4       currentTabIndex:index,
5     })
6   }

  使用wx:for将数据渲染到页面中,使用availabel判断为哪种优惠券,从而渲染到不同的选项下,并绑定不同的样式

 1  <view class="card"  wx:for="{{price}}" wx:if="{{item.available!=0}}">
 2           <view class="left-2">
 3             <view class="left-title">¥{{item.count}}</view>
 4             <view class="left-under">满{{item.money}}元可用</view>
 5           </view>
 6           <view class="word">
 7               <view class="title">
 8                 {{item.name}}
 9               </view>
10               <view class="under">
11
12                {{item.day}}
13               </view>
14           </view> 
15         </view>

 

  pages/policy/policy、pages/rule/rule、pages/set/set  :(三张简单的内容页面,不过多赘述)

                   

 

  pages/main/main(主页):

  上方为与个人信息页相同的授权判定,授权则显示用户信息,未授权则显示登录按钮。签到按钮通过全局变量中的sign判断是否曾签到过,并在签到后改变样式

        

  main.wxml

1     <view class="{{style}}" bindtap="sign" >{{sign}}</view>

  main.js

 1 var util = require('../../utils/util.js');                   //导入官方自带的js文件,内含时间处理函数
 2  sign:function(){
 3       if( app.globalData.sign=="签到")                        //判断是否曾签到
 4       {
 5         console.log("ok")
 6         app.globalData.sign="已签"                   
 7         app.globalData.style="qd-1"                            //改变样式
 8         app.globalData.scorenum=app.globalData.scorenum+2      //改变总积分
 9         var newpoint={                                          
10           day: util.formatTime(new Date()),
11           title:"签到奖励",
12           point:2
13         }
14         app.globalData.score.unshift(newpoint);                 //在积分信息数组中加入新的数据
15         this.setData({                                          //修改当前界面的数据,及时刷新
16             style:"qd-1", 
17             sign:"已签",
18             score:app.globalData.scorenum
19         })
20       }else{
21       }
22   },

  下方使用swiper组件实现轮播

 

  pages/show/show(领券页面):

  领券按钮主要通过全局变量disabled判断是否已经领过券,第一次领取则领取成功并弹窗

       

  show.wxml

1    <button disabled="{{disabled}}" bindtap="get" style="width:200rpx;color:white;background-color:{{color}}" >领取</button>

  show.js

  get(){
    wx.showToast({                                        //弹窗
      title: '领取成功!', // 标题
      icon: 'success',  // 图标类型,默认success
      duration: 1500  // 提示窗停留时间,默认1500ms
    }),
    app.globalData.color="grey",
    app.globalData.disabled=true,
    app.globalData.pricenum+=1,                           //修改了全局变量
    console.log(app.globalData.disabled)
    this.setData({
     color:"grey",
     disabled:true                                        //在当前界面更新
    })
    var newprice={
      available:0,
      count:2,
      money:4,
      name:"雪碧满4减2券",
      day:"2020.1.1-2021.1.1可用"
    }
    app.globalData.price.push(newprice)                    //将新的优惠券信息插入全局数组中

    
  },

 

  pages/score/score(积分界面):

  积分信息的渲染同优惠券界面,筛选功能通过picker组件控制,选择后重置当前界面的数组,使得当前界面的信息发生改变

  

  score.wxml

1 <picker  mode="selector" bindchange="bindPickerChange" value="{{index}}" range="{{array}}">
2         <view class="button" >筛选</view>
3 </picker>

  score.js

 1  data: {
 2     array: ['全部', '增加', '减少'],        //绑定在选择器的数据
 3     objectArray: [                        
 4       {
 5         id: 0,
 6         name: '全部'
 7       },
 8       {
 9         id: 1,
10         name: '增加'
11       },
12       {
13         id: 2,
14         name: '减少'
15       }
16     ],
17     index: 0                               //当前所选的条目的下标
18   },
 1  bindPickerChange: function (e) {
 2     console.log('picker发送选择改变,携带值为', e.detail.value)
 3     this.setData({
 4       index: e.detail.value                             //绑定选择的下标
 5     })
 6     if(e.detail.value==0)                               //下标为0则全选,将完整的数组赋值给当前
 7     {
 8       this.setData({
 9         score:app.globalData.score
10       })
11     }else if(e.detail.value==1){                         //下标为1,选择增加积分的页面
12      var i;
13      var temp=[];
14      for(i=0;i<app.globalData.score.length;i++)           //遍历数组,找出增值为正的值存入中间tmp数组
15      {
16        if(app.globalData.score[i].point>0){
17             temp.push(app.globalData.score[i]);
18        }
19      }
20      this.setData({
21       score:temp                                          //修改为处理后的数组
22     })
23     }else{                                                 //检索减少的值为同理
24       var i;
25       var temp=[];
26       for(i=0;i<app.globalData.score.length;i++)
27       {
28         if(app.globalData.score[i].point<0){
29              temp.push(app.globalData.score[i]);
30         }
31       }
32       this.setData({
33        score:temp
34      })
35     }
36   }

 

   pages/shop/shop(积分商城):

   通过wx:for将商品信息绑定至界面。点击时将点击的商品卡片对应的信息传入函数,函数比较当前积分和商品所需积分,满足需求弹出确认窗口,积分不足则弹出提示框

         

   shop.wxml

 1 <view class="card-group" >
 2     <view class="card" wx:for="{{shop}}" wx:key="{{item.index}}" bindtap="buy" data-item="{{item}}">
 3     <image class="img" src="{{item.src}}">
 4     </image>
 5     <view class="title">
 6    {{item.title}}
 7     </view >
 8     <view class="score">
 9        {{item.point}}积分
10     </view>
11  </view>

  shop.js

 1  buy(e){
 2        var good = e.currentTarget.dataset.item;                   //获得当前商品信息
 3        if(good.point>=app.globalData.scorenum)                    //比较积分是否满足
 4        {
 5         wx.showToast({                                             //积分不足,弹出纯文字信息
 6           title: '积分不足',
 7           icon: 'none',    //如果要纯文本,不要icon,将值设为'none'
 8           duration: 2000     
 9         })  
10        }else{ 
11         let that = this;                                            //保存当前page信息,在后续回调函数中this将无法调用
12         wx.showModal({                                              //确认框
13               title:"确认",
14               content:"将扣除500积分,您确定吗?",
15               success:function(res){                                 //确认兑换,扣除积分
16               if(res.confirm){
17                   app.globalData.scorenum-=good.point;
18                  
19                   that.setData({
20                     score:that.data.score-good.point
21                   })
22                   wx.showToast({
23                   title: '兑换成功',
24                   icon: 'none', 
25                   duration: 1000     
26                 })  
27 
28                 var newprice={
29                   available:0,
30                   count:1,
31                   money:3,
32                   name:"可乐满3减1券",
33                   day:"2020.1.1-2021.1.1可用"
34                 }
35                 app.globalData.price.push(newprice);                //把兑换的券加入券的数组
36 
37                 var newpoint={
38                   day: util.formatTime(new Date()),
39                   title:"兑换商品",
40                   point:-500
41                 }
42                 app.globalData.score.unshift(newpoint);               //吧兑换的积分信息加入积分信息的数组
43                 app.globalData.pricenum+=1;
44               }
45               else if(res.cancel){
46                 wx.showToast({                                          //取消兑换,弹出信息
47                   title: '已经取消',
48                   icon: 'none',    //如果要纯文本,不要icon,将值设为'none'
49                   duration: 1000     
50                 })  
51               }}
52         })
53        }
54     },

 

  收获总结

  虽然是软件工程作业的第一份作业,也着实花了不少功夫,从0基础到完成一份较为完善的小demo,一步步查找文档和资料,将一个个功能完善。其中也经过了不少的弯路,犯了不少错误。希望在今后的编码中,可以吸取这次开发的经验,将这次写demo的经验用在之后的大作业和编码中。同时,可以继续保持认真学习,自主学习的态度,同时向周围优秀的同学学习,继续完善持续跟进软件工程的学习。

  

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM