小程序,巧应用:微信小程序开发实战
上QQ阅读APP看书,第一时间看更新

第2章 小程序初体验

上一章我们成功地创建了第一个示例小程序——Hello WXapplet。本章通过解析这个小程序项目,使大家尽可能对小程序有个全局的认知,包括小程序的框架、目录结构、开发步骤以及入口界面、示例代码的使用与运行等。

2.1 理解小程序

对于用户而言,小程序的直观表现只是多个相互关联的页面。我们的小程序Hello WXapplet也一样,它由2个相互关联的页面构成:首页(index)与信息页(logs)。点击首页的头像就切换到信息页,在信息页点击“返回”可以从信息页返回到首页,如图2-1所示。

图2-1 两个相互关联的页面

小程序的开发实际上就是实现这些页面的展示(视图),以及实现“页面上用户交互事件”、“页面间切换逻辑”、“数据存储及网络调用”等事务与逻辑处理的过程。

2.1.1 Hello WXapplet项目目录及文件构成

我们先从文件目录结构上来了解Hello WXapplet项目的构成。点击开发者工具左侧导航的“编辑”,我们可以看到Hello WXapplet项目的目录结构及包含文件如图2-2所示。

图2-2 Hello WXapplet项目的目录结构

目录结构显示:小程序项目在创建时的目录(示例的本地开发目录为:“D:\小程序巧应用”)之下,包含3个app开头的文件(app.js、app.json、app.wxss)以及pages目录与utils目录。其中pages目录存放2个页面(index与logs)的构成文件。从示例中,我们看到:每个页面都是一个目录,目录名就是唯一的页面名,其下再由以页面名为前缀的2~4个文件组成。

对小程序的目录文件结构,我们可以归纳一下,如图2-3所示。

图2-3 小程序的目录文件结构

左侧3个app文件必须放在小程序根目录下,其他文件则由开发者自由控制。这3个文件说明如下:

■ app.js是小程序的脚本代码,用来监听并处理小程序的生命周期函数、声明全局变量。

■ app.json是对整个小程序的全局配置,配置小程序是由哪些页面组成,配置小程序的窗口背景色等。

■ app.wxss是整个小程序的公共样式表。

其中app.js和app.json是必需的。

小程序页面是由同路径下同名但不同后缀的2~4个文件组成:

■.js后缀的文件是脚本文件。

■.json后缀的文件是配置文件。

■.wxss后缀的是样式表文件。

■.wxml后缀的文件是页面结构文件。

其中.js与.wxml文件是必需的。

2.1.2 Hello WXapplet项目的代码实现

我们再从代码层面了解Hello WXapplet项目的实现,根据小程序的目录结构,代码实现有两大部分——小程序实例与页面,下面分别介绍。

1.小程序实例的代码实现

在Web开发者工具的“编辑”模式下,我们来看Hello WXapplet这个项目里的代码文件,最关键也必不可少的是app.js、app.json、app.wxss这三个文件,分别代表脚本文件、配置文件、样式表文件。微信小程序运行时会读取这些文件,并生成小程序实例。

app.js脚本代码用于监听并处理小程序的生命周期函数、声明全局变量、调用框架提供的丰富的API等。如本例app.js文件中,我们调用了的同步存储及同步读取本地数据的API——wx.setStorageSync()及wx.getStorageSync()。代码见程序清单2-1。想了解更多可用API,可参考本书第5章“API接口的开发应用”。

程序清单2-1 小程序app.js

        // app.js
        App({
          onLaunch: function () {
            // 调用API从本地缓存中获取数据
            var logs = wx.getStorageSync('logs') || []
            logs.unshift(Date.now())
            wx.setStorageSync('logs', logs)
          },
          getUserInfo:function(cb){
            var that = this;
            if(this.globalData.userInfo){
              typeof cb == "function" && cb(this.globalData.userInfo)
            }else{
                // 调用登录接口
                wx.login({
                  success: function () {
                    wx.getUserInfo({
                      success: function (res) {
                        that.globalData.userInfo = res.userInfo;
                        typeof cb == "function" && cb(that.globalData.userInfo)
                      }
                    })
                  }
                });
              }
            },
            globalData:{
              userInfo:null
            }
          })

app.json配置文件是对整个小程序的全局配置,代码见程序清单2-2。开发者将在这个文件中配置小程序是由哪些页面组成、配置小程序的窗口背景色、配置导航条样式、配置默认标题等。

注意 app.json不可添加任何注释。

更多关于小程序的全局配置项可参考本书3.1节。

程序清单2-2 小程序app.json

        {
          "pages":[
            "pages/index/index",
            "pages/logs/logs"
          ],
          "window":{
            "backgroundTextStyle":"light",
            "navigationBarBackgroundColor": "#fff",
            "navigationBarTitleText": "WeChat",
            "navigationBarTextStyle":"black"
          }
        }

app.wxss样式表文件是整个小程序的公共样式表,代码见程序清单2-3。我们可以在页面“组件”的class属性上直接使用app.wxss中声明的样式规则。

关于.wxss文件中的样式规则可参考本书3.3.2节“wxss详解”。

程序清单2-3 小程序app.wxss

        /**app.wxss**/
        .container {
          height: 100%;
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: space-between;
          padding: 200rpx 0;
          box-sizing: border-box;
        }

2.小程序页面的代码实现

在我们创建的Hello WXapplet小程序项目中,包含两个页面——index页面和logs页面,即首页和小程序启动日志的展示信息页,它们都在pages目录下。

每一个小程序页面可由同路径下同名的2~4个不同后缀文件组成,如:Hello WXapplet小程序的index页面就由pages目录下index路径中index.js、index.wxml、index.wxss、index.json四个文件组成,它们分别是页面脚本文件、页面结构文件、页面样式表文件、页面配置文件。其中,.wxml与.js文件是页面所必需的,而.wxss与.json文件则是可选的。

注意 微信小程序中的每一个页面的“路径+页面名”都需要写在app.json的pages中,且pages中的第一个页面是小程序的首页。.wxml文件与.wxss文件作为小程序开发框架的一部分,我们在第3章会详细介绍。

下面分别介绍index页面与logs页面。

index.wxml是页面的结构文件,代码见程序清单2-4。

程序清单2-4 页面结构index.wxml

        <! --index.wxml-->
        <view class="container">
          <view   bindtap="bindViewTap" class="userinfo">
            <image class="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size=
              "cover"></image>
            <text class="userinfo-nickname">{{userInfo.nickName}}</text>
          </view>
          <view class="usermotto">
            <text class="user-motto">{{motto}}</text>
          </view>
        </view>

index.wxml文件中使用了<view/>、<image/>、<text/>这三个组件来搭建页面结构,绑定数据和交互处理函数。有关页面组件的详细使用可以参考本书第4章。

index.js是页面的脚本文件,代码见程序清单2-5。我们在这个文件中监听并处理页面的生命周期函数~onLoad(),获取小程序实例~getApp(),声明并处理数据,响应页面交互事件等。

程序清单2-5 页面脚本index.js

        // index.js
        // 获取应用实例
        var app = getApp()
        Page({
          data: {
            motto: 'Hello World',
            userInfo: {}
          },
          // 事件处理函数
          bindViewTap: function() {
            wx.navigateTo({
              url: '../logs/logs'
            })
          },
          onLoad: function () {
            console.log('onLoad')
            var that = this
            // 调用应用实例的方法获取全局数据
            app.getUserInfo(function(userInfo){
              // 更新数据
              that.setData({
                userInfo:userInfo
              })
            })
          }
        })

从上面的代码我们可以知道,.js文件是页面逻辑处理层。详细的逻辑层编码请参考本书3.2节。

index.wxss是页面的样式表文件,代码见程序清单2-6。

程序清单2-6 页面样式index.wxss

        // index.wxss
        .userinfo {
          display: flex;
          flex-direction: column;
            align-items: center;
          }
          .userinfo-avatar {
            width: 128rpx;
            height: 128rpx;
            margin: 20rpx;
            border-radius: 50%;
          }
          .userinfo-nickname {
            color: #aaa;
          }
          .usermotto {
            margin-top: 200px;
          }

页面的样式表文件是非必要的。当页面有样式表文件时,文件中的样式规则会层叠覆盖app.wxss中的样式规则。否则,即使没有页面样式表文件,我们也可以在页面的结构文件中直接使用app.wxss中指定的样式规则。

index.json是页面的配置文件。页面的配置文件同样是非必要的。当页面有配置文件时,文件中的配置项在该页面上会覆盖app.json的window中相同的配置项。若没有指定页面的配置文件,则在该页面直接使用app.json中的默认配置项。更多配置文件编写与解析,可参考本书3.1节。

接下来我们再看看logs页面。logs.wxml是logs页面的结构文件,代码见程序清单2-7。

程序清单2-7 页面结构logs.wxml

        <! --logs.wxml-->
        <view class="container log-list">
          <block wx:for="{{logs}}" wx:for-item="log">
            <text class="log-item">{{index + 1}}. {{log}}</text>
          </block>
        </view>

logs页面使用<block/>控制标签来组织代码,在<block/>上使用控制属性wx:for绑定logs数据,并将logs数据循环展开节点。

注意 上述代码中的<block/>并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性(如wx:for或wx:if)。

logs.js是logs页面的脚本文件,代码见程序清单2-8。

程序清单2-8 页面脚本logs.js

        // logs.js
        var util = require('../../utils/util.js')
        Page({
          data: {
            logs: []
          },
          onLoad: function () {
            this.setData({
              logs: (wx.getStorageSync('logs') || []).map(function (log) {
                return util.formatTime(new Date(log))
              })
            })
          }
        })

上述脚本文件代码中,使用了require()来引入模块化.js脚本文件。关于模块化代码,可参考本书3.2.3节。