小程序教程

微信小程序(应用号)实战课程之记账应用开发

字号+ 作者: 来源: 2016-11-23 09:49 我要评论( )

通过阅读本课程你可以学到以下知识:

1.使用表单组件、表单验证、Alert警告框

2.实现列表页并重写单元格

3.保存与读取数据到本地

4.页面跳转

先看一上效果图

图0-1

图0-2

一、创建项目并勾上quickStart

如图1-1

二、首页

首页包含一个添加收支按钮与所有条目的列表

1. 首页布局

1.1 增加一个添加按钮

  1. <!--index.wxml-->
  2. <view class="container">
  3.     <navigator url="../item/item" hover-class="navigator-hover">添加收支</navigator>
  4. </view>
复制代码

1.2 设置按钮按下高亮样式hover-class

  1. /**index.wxss**/

  2. /** 修改默认的navigator点击态 **/
  3. .navigator-hover {
  4.     color:#2297f1;
  5. }
复制代码

2. 添加页面布局

依次新建一个item文件夹,item.wxml item.wxss item.js item.json

如图2-2-1

修改app.json

  1. {
  2.   "pages":[
  3.     "pages/index/index",
  4.     "pages/item/item"
  5.   ],
  6.   "window":{
  7.     "backgroundTextStyle":"light",
  8.     "navigationBarBackgroundColor": "#2297f1",
  9.     "navigationBarTitleText": "灵犀账本",
  10.     "navigationBarTextStyle":"white"
  11.   }
  12. }
复制代码

item.wxml

  1. <!--item.wxml-->
  2. <view class="page">
  3.     <view class="section">
  4.         <view class="section__title">标题</view>
  5.         <input bindinput="bindTitleInput" placeholder="内容" value="{{title}}" />
  6.     </view>
  7.     <view class="section">
  8.         <view class="section__title">类型</view>
  9.         <radio-group class="radio-group" bindchange="radioChange">
  10.             <label class="radio">
  11.                 <radio class="radio" value="income" checked="true"/>收入
  12.             </label>
  13.             <label class="radio">
  14.                 <radio class="radio" value="cost"/>支出
  15.             </label>
  16.         </radio-group>
  17.     </view>
  18.     <view class="section">
  19.         <view class="section__title">金额</view>
  20.         <input bindinput="bindAccountInput" type="number" placeholder="请输入数字,不加正负号"/>
  21.     </view>
  22.     <button class="button" type="primary">添加</button>
  23. </view>
复制代码

item.wxss

  1. .page {
  2.     min-height: 100%;
  3.     flex: 1;
  4.     background-color: #FBF9FE;
  5.     font-size: 32rpx;
  6.     font-family: -apple-system-font,Helvetica Neue,Helvetica,sans-serif;
  7.     overflow: hidden;
  8. }

  9. .page input{
  10.     padding: 20rpx 30rpx;
  11.     background-color: #fff;
  12. }

  13. .section{
  14.     margin:40rpx 0;
  15. }
  16. .section_gap{
  17.     padding: 0 30rpx;
  18. }
  19. .section__title{
  20.     margin-bottom: 16rpx;
  21.     padding-left: 30rpx;
  22.     padding-right: 30rpx;
  23. }
  24. .section_gap .section__title{
  25.     padding-left: 0;
  26.     padding-right: 0;
  27. }

  28. .radio-group {
  29.     margin:50rpx;
  30.     font-size:25rpx;
  31. }

  32. .radio{
  33.     margin-right: 20rpx;
  34. }

  35. /**按钮**/
  36. .button {
  37.     margin:10rpx;
  38. }
复制代码

item.js

  1. // item.js
  2. Page({
  3.   data: {
  4.     title: '',
  5.     cate:'',
  6.     account: ''
  7.   },
  8. //   标题文本框
  9.   bindTitleInput: function(e) {
  10.       this.setData( {
  11.           title: e.detail.value
  12.       })
  13.     console.log(e.detail.value)
  14.   },
  15. //   金额radio
  16.   radioChange: function(e) {
  17.       this.setData({
  18.           cate: e.detail.value
  19.       })
  20.     console.log(e.detail.value)
  21.   },
  22. //   金额文本框  
  23.   bindAccountInput: function(e) {
  24.       this.setData( {
  25.           account: e.detail.value
  26.       })
  27.     console.log(e.detail.value)
  28.   },
  29. })
复制代码

item.json

  1. {
  2.     "navigationBarTitleText": "添加收支"
  3. }
复制代码

查看效果:

如图2-2-2

3.1

保存数据到本地存储

在item.js文件中创建save方法并与视图绑定

  1. // item.js
  2. Page({
  3.   data: {
  4.     title: '',
  5.     cate:'',
  6.     account: '',
  7.     modalHidden: true
  8.   },
  9. //   标题文本框
  10.   bindTitleInput: function(e) {
  11.       this.setData( {
  12.           title: e.detail.value
  13.       })
  14.     // console.log(e.detail.value)
  15.   },
  16. //   金额radio
  17.   radioChange: function(e) {
  18.       this.setData({
  19.           cate: e.detail.value
  20.       })
  21.     // console.log(e.detail.value)
  22.   },
  23. //   金额文本框  
  24.   bindAccountInput: function(e) {
  25.       this.setData( {
  26.           account: e.detail.value
  27.       })
  28.     // console.log(e.detail.value)
  29.   },
  30.   save: function() {
  31.     var that = this
  32.     // 本条数据打包成json
  33.     var record = {
  34.       title: this.data.title,
  35.       cate: this.data.cate,
  36.       account: this.data.account,
  37.     }
  38.     var data = []

  39.     wx.getStorage({
  40.       key: 'db',
  41.       success: function(res) {
  42.         console.log('db:' + res.data)
  43.         data = res.data
  44.         // 取出本地数据
  45.         data.push(record)
  46.         // 存回本地
  47.         wx.setStorage({
  48.           key: 'db',
  49.           data: data
  50.         })

  51.         // 提示框
  52.         that.setData({
  53.           modalHidden: false
  54.         });
  55.       }
  56.     })
  57.   },
  58.   // 使用onShow而不使用onLoad,使得添加返回后自刷新
  59.   onShow: function() {
  60.     wx.getStorage({
  61.       key: 'db',
  62.       // 初始加载无数据,故插入一条空数组的新key
  63.       fail: function() {
  64.                 // 存回本地
  65.         wx.setStorage({
  66.           key: 'db',
  67.           data: []
  68.         })
  69.       }
  70.     })
  71.   },

  72.   // 关闭对话框
  73.   hideAlertView: function() {
  74.     this.setData({
  75.       'modalHidden': true
  76.     })
  77.     // 返回上一页
  78.     wx.navigateBack()
  79.   }

  80. })
复制代码

值得注意的是:setStorage是包在getStorage方法回调事件里,保证线程一致性,即使使用了Sync方式的方法,依次不能保证数据同步,经多次实践发现getStorage方法是最后被调的,于是就无法取出原来的数据,也就不能追加本条数据了。

与视图绑定添加按钮的点击事件与弹窗的点击事件

  1. <button class="button" type="primary" bindtap="save">添加</button>
  2. <modal class="modal" hidden="{{modalHidden}}" no-cancel bindconfirm="hideAlertView">
  3.   <view>添加成功</view>
  4. </modal>
复制代码

四、首页读取列表

1.首页布局

  1. <!--index.wxml-->

  2. <view class="container news-list">
  3.   <view class="navi">
  4.     <button class="add-button" size="mini" type="primary" bindtap="addItem">添加收支</button>
  5.   </view>
  6.   <block wx:for="{{items}}">
  7.     <view class="news-item" data-title="{{item.title}}">
  8.       <view class="news-text">
  9.         <text class="news-title">{{item.title}}</text>
  10.         <view class="news-stamp">
  11.           <text>{{item.cate}} {{item.account}}</text>
  12.           <text>2016-9-29{{item.date}}</text>
  13.         </view>
  14.       </view>
  15.     </view>
  16.   </block>
  17. </view>
复制代码

2.首页样式

  1. /**index.wxss**/

  2. /*添加按钮*/
  3. .navi {
  4.   width:100%;
  5. }

  6. .add-button {
  7.   float: right;
  8. }

  9. /*列表*/
  10. .news-list {
  11.   display: flex;
  12.   flex-direction: column;
  13.   padding: 40rpx;
  14. }

  15. .news-item {
  16.   display: flex;
  17.   flex-direction: row;
  18.   text-align: left;
  19.   width: 100%;
  20. }

  21. .news-text {
  22.   display: flex;
  23.   flex-direction: column;
  24.   width:100%;
  25.   border-bottom: 1px solid #ccc;
  26.   line-height: 30px;
  27. }

  28. .news-stamp {
  29.     font-size: 30rpx;
  30.     color:darkgray;
  31.     margin: 20rpx;
  32.     display: flex;
  33.     flex-direction: row;
  34.     justify-content:space-between;
  35. }

  36. .news-title {
  37.   margin: 20rpx;
  38.   margin-bottom: 0rpx;
  39.   font-size: 40rpx;
  40. }
复制代码

3.首页js

  1. //index.js
  2. //获取应用实例
  3. Page({
  4.   data: {
  5.       items: []
  6.   },
  7.   addItem: function() {
  8.       wx.navigateTo({
  9.       url: '../item/item'
  10.     })
  11.   },
  12.   onLoad: function () {
  13.     var that = this
  14.     wx.getStorage({
  15.       key: 'db',
  16.       success: function(res) {
  17.         console.log(res.data.length);
  18.         that.setData({
  19.           'items':res.data
  20.         });
  21.       }
  22.     })
  23.   }
  24. })
复制代码

检查效果,如图4-1

结语

整体开发过来,还是比较自然的。有几个要点值得注意:

  • getStorage的异步性;this的作用域,声明var that = this,才可以在success回调函数中访问。
  • AlertView模态窗口的写法,要通过绑定数据到<modal>的hidden属性,这跟以往弹窗的写法都不相同,体现小程序数据自动刷新的思想。

3.在wxss中使用流程控制跟平时的思路也不一样,是定位于整个view而言的,于是为出支红绿着色只能写成这样形式:

  1.           <text wx:if="{{item.cate == '-'}}" class="sign-green">{{item.cate}} {{item.account}}</text>
  2.           <text wx:else class="sign-red">{{item.cate}} {{item.account}}</text>
复制代码

这种形式比较冗余,能直接写在class中就好了。

本打算再做一个日期选择,演示Picker的写法,但发现官网文档上的没有实现,而普通自定义数据的Picker却可行,找到方法再来更新本教程与git源。



 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 微信小程序 轮播图 swiper图片组件

    微信小程序 轮播图 swiper图片组件

    2016-11-23 09:49

  • 微信小程序 开发 微信开发者工具 快捷键

    微信小程序 开发 微信开发者工具 快捷键

    2016-11-23 09:49

  • 微信小程序 页面跳转 传递参数

    微信小程序 页面跳转 传递参数

    2016-11-23 09:49

  • 微信小程序 如何获取时间

    微信小程序 如何获取时间

    2016-11-23 09:49

网友点评