在这个文件中,代码并不多,而且也比较容易。
- //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))
- })
- })
- }
- })
在一开始demo引入了一个工具,其实就是utils文件夹中的文件:
- var util = require('../../utils/util.js')
对了,在上一篇中没有提到,在App({...})或者Page({...})方法外定义的变量是一个全局变量,在这个文件中都可以使用。
照例,在这个page文件的data中定义了一个logs数组变量,这个变量是个老朋友,因为在app.js中也有一个这样类似的变量:
- var logs = wx.getStorageSync('logs') || []
在onLoad中应证了我的想法,他用到了本地缓存中的logs:
- logs: (wx.getStorageSync('logs') || []).map(function (log) {
- return util.formatTime(new Date(log))
- })
这个时候唯一不太明白的是map方法和util这个变量的方法。首先看map方法,这个必须结合页面来看,它达到的效果是:
首先我们肯定的是logs是一个数组,wx.getStorageSync('logs')获取的正是一个数组,所以说map是一个数组方法。其次页面上展示了一行一行的时间,所以说map会遍历数组,从0开始(所有语言数组几乎都是从0开始),其次map的参数是一个方法,其中这个方法还带了一个参数log,我大胆猜测这个log即是数组中的内容,因此,map会遍历数组每一项而且都会进行一次function(log){}方法(笔者曾试过百度map方法,查到的内容比较规范但是特别杂繁琐,针对本demo而言我觉得更适合用拆分方法来解释map的用法)。
既然清楚了map的方法实现,我们再来看看util变量实现了什么方法:
- util.formatTime(new Date(log))
- function formatTime(date) {
- var year = date.getFullYear()
- var month = date.getMonth() + 1
- var day = date.getDate()
- var hour = date.getHours()
- var minute = date.getMinutes()
- var second = date.getSeconds()
- return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
- }
- function formatNumber(n) {
- n = n.toString()
- return n[1] ? n : '0' + n
- }
- module.exports = {
- formatTime: formatTime
- }
这是个简单的js文件,而在这个文件中我们没有看到App({...})或者Page({...})类似的方法,只是单纯的罗列了三个方法function formatTime(),function formatNumber(),module.exports,显而易见的是前面两个方法应该是一个公开方法,因为在logs.js中已经调用过formatTime:
- util.formatTime(new Date(log))
- var n = util.formatNumber(1)
成功了么?答案是否定的,而且控制台报了这样的错误: util.formatNumber is not a function;at "pages/logs/logs" page lifeCycleMethod onLoad function
这是为什么?答案就在这里:
- module.exports = {
- formatTime: formatTime
- }
- fn : formatNumber
为了区别两个参数的不同,笔者专门把自己自定义的方法名简写了,然后将
- var n = util.formatNumber(1)
- var n = util.fn(1)
红框中的01正是方法的返回值,所以说如果想要写工具类让其他类使用,需要module.exports来定义你的公开方法。
- function formatTime(date) {
- var year = date.getFullYear()
- var month = date.getMonth() + 1
- var day = date.getDate()
- var hour = date.getHours()
- var minute = date.getMinutes()
- var second = date.getSeconds()
- return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
- }
- function formatNumber(n) {
- n = n.toString()
- return n[1] ? n : '0' + n
- }
- [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
之后有一个join('/')方法,这个最直观的从界面上就可以判断出在数组每一项后面加上/,并且在最后一个下标的值忽略不实现,这样我们就可以获得我们经常看到的年月日格式2017/01/10。在后面的时分秒也是同理。
基本上logs.js也看完了,接下来分析logs.json。在这里有一些内容,并不是全空的:
- {
- "navigationBarTitleText": "查看启动日志"
- }
记得在app.json中也有个参数叫做navigationBarTitleText:
- "navigationBarTitleText": "WeChat",
我们在这里同样写了这个东西有什么用呢?很简单直接把我们的标题改变了呗:
由此我们得到一个结论,子类的配置文件json修改相同参数,优先显示子类的json配置,然后再显示父类的。当然,可以应证一下原理,我们在logs.json中把标题改为蓝色,这样的效果应该是首页的WeChat颜色不变,而查看启动日志变为了蓝色:
- "navigationBarTextStyle":"blue"
bingo,原理正确。
在logs.wxml中我们又看到了有趣的东西:
- <!--logs.wxml-->
- <view class="log-list">
- <block wx:for="{{logs}}" wx:for-item="log" wx:key="*this">
- <text class="log-item">{{index + 1}}. {{log}}</text>
- </block>
- </view>
<block>这个东西,block英文是块,所以说这个就是一块一块的意思。我们记得{{}}中的是js中的变量,所以logs是一个数组。在这里为了显示数组数据,微信用的是wx:for这个语句。这倒是像我们写for int i = 0;i < count;i++的循环语句。wx:for-item获取到的应该是数组每一个值,而"log"则被赋予了这个值的别名,我们用log就能代表数组中的值。wx:key="*this"很晦涩难懂,在这里我们感觉是一个毫无相关的东西,因此完全不能乱猜,这里我们最好的解决方案:查找官方文档。
文档内容:
wx:key
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如<input/>
中的输入内容,<switch/>
的选中状态),需要使用 wx:key
来指定列表中项目的唯一的标识符。
wx:key
的值以两种形式提供
- 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
- 保留关键字
*this
代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字,如:
当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
如不提供 wx:key
,会报一个warning
, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
文档中所述最简单的解释在这里就是*this指的是数组中的item本身,而且在静态数组中有了这个值提高了渲染效率。这个参数暂时在这里不深入研究,笔者也只是略懂了点皮毛,技术有限请谅解。
这里还有一个神奇的参数index,这个应该是默认生成给开发者调用下标用的,咱们用就是了。
在这里我们还是没有清楚block的用法,最简单的还是得结合图看:
我们通过block的方法,获得了一个列表,所以不用想,block就是一行一行的数据,它的用法就是将内容以块来显示,然后批量使用。在这里我们block中只有text,所以暂时看不出block的强大,我们再加一个view进去:
logs.wxml中
- <!--logs.wxml-->
- <view class="log-list">
- <block wx:for="{{logs}}" wx:for-item="log" wx:key="*this">
- <text class="log-item">{{index + 1}}. {{log}}</text>
- <view class="blockView">asd</view>
- </block>
- </view>
logs.wxss中
- .log-list {
- display: flex;
- flex-direction: column;
- padding: 40rpx;
- background: gray;
- }
- .log-item {
- margin: 10rpx;
- text-align: center;
- }
- .blockView {
- background: blue;
- }
再来看显示结果:
现在很明显了,以block中的内容为一块内容,我们创建出了一个列表。在以后的开发中,我相信大家会使用更多的block,实践出真知,大家会越用越熟练的。
最后的一个wxss文件我就不加阐述了,样式这个东西除了练还是练,希望笔者与大家一起进步,早日练到运用自如。自此,整个demo全部研究透彻,作为 微信小程序开发学习,我们要学以致用,从学习中举一反三,祝大家早日开发出自己的小程序