购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

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后缀的文件是页面结构文件,该文件与.wxss文件一起构建出页面。

其中.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从本地缓存中获取数据
     // 定义一个数组变量logs
var logs = wx.getStorageSync('logs') || []
// 在数组logs的集合开头插入一个元素,值为当前时间
logs.unshift(Date.now())
// 将数组logs写入本地名为logs缓存块中
    wx.setStorageSync('logs', logs)
  },
  // 定义一个后面index.js中会调用到的函数,参数cb意为callback,即回调函数*
  getUserInfo:function(cb){
    var that = this;
if(this.globalData.userInfo){
  // 判断cb是否存在且为function类型,若是则传进参数调用cb
      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
  }
})

注意 没有编程基础的读者很容易被上述代码中的“回调函数”打蒙圈,这种情况建议先百度或Google了解一下“回调函数”的概念。

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;
}

app.wxss文件中上述程序代码定义了一个名为container的样式。

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文件作为小程序开发框架的一部分,我们在本章后面会详细介绍。

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

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

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


<!--index.wxml-->
<!--下一行代码使用view组件,构建样式为container的视图块-->
<view class="container">
  <!--下一行代码使用view组件,构建样式为userinfo的视图块,并绑定tap事件到
    bindViewTap事件处理函数,该事件处理函数在页面js文件定义-->
  <view  bindtap="bindViewTap" class="userinfo">
    <!--下一行代码使用image组件,放置样式userinfo-avatar的图片,图片地址为变量
      userInfo.avatarUrl。形如{{var}}的变量,即双大括号包含的动态数据变量,其值
      来自页面js文件中的data对象 -->
<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是页面的配置文件。页面的配置文件同样是非必要的,而且只能配置window配置项的属性值。当页面有配置文件时,文件中的配置项在该页面上会覆盖app.json的window中相同的配置项。若没有指定页面的配置文件,则在该页面直接使用app.json中的默认配置项。更多配置文件编写与解析,可参考本书3.1节。

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

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


<!--logs.wxml-->
<view class="container log-list">
  <!--for循环的方式绑定数据,并指定数组元素的变量名为log-->
  <block wx:for="{{logs}}" wx:for-item="log">
      <!--数组当前元素下标变量名默认为index-->
    <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数组的每个元素使用map方法:即调用匿名回调函数并返回包含结果的数组
      logs: (wx.getStorageSync('logs') || []).map(function (log) {
        return util.formatTime(new Date(log))
      })
    })
  }
})

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

点击中间区域
呼出菜单
上一章
目录
下一章
×