国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > php开源 > 综合技术 > 微信小程序上手篇(3)

微信小程序上手篇(3)

来源:程序员人生   发布时间:2018-06-11 17:18:12 阅读次数:7831次

  还只剩最后1个page需要研究了,成功的曙光就在眼前。

  在这个文件中,代码其实不多,而且也比较容易。

//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))
      })
    })
  }
})

  在1开始demo引入了1个工具,其实就是utils文件夹中的文件:

var util = require('../../utils/util.js')
  我们可以看到微信是用require来引入的,其实在官方文档中还有import和include引入,不过各司其职,需要读者自己去看官方文档研究。

  对了,在上1篇中没有提到,在App({...})或Page({...})方法外定义的变量是1个全局变量,在这个文件中都可使用。

  照例,在这个page文件的data中定义了1个logs数组变量,这个变量是个老朋友,由于在app.js中也有1个这样类似的变量:

var logs = wx.getStorageSync('logs') || []

  在onLoad中应证了我的想法,他用到了本地缓存中的logs:

   logs: (wx.getStorageSync('logs') || []).map(function (log) {
        return util.formatTime(new Date(log))
      })

  这个时候唯1不太明白的是map方法和util这个变量的方法。首先看map方法,这个必须结合页面来看,它到达的效果是:

  首先我们肯定的是logs是1个数组,wx.getStorageSync('logs')获得的正是1个数组,所以说map是1个数组方法。其次页面上展现了1行1行的时间,所以说map会遍历数组,从0开始(所有语言数组几近都是从0开始),其次map的参数是1个方法,其中这个方法还带了1个参数log,我大胆猜想这个log即是数组中的内容,因此,map会遍历数组每项而且都会进行1次function(log){}方法(笔者曾试过百度map方法,查到的内容比较规范但是特别杂繁琐,针对本demo而言我觉得更合适用拆分方法来解释map的用法)。

  既然清楚了map的方法实现,我们再来看看util变量实现了甚么方法:

util.formatTime(new Date(log))
  我们直接跳转到utils文件夹,点击看源码:

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({...})类似的方法,只是单纯的罗列了3个方法function formatTime(),function formatNumber(),module.exports,不言而喻的是前面两个方法应当是1个公然方法,由于在logs.js中已调用过formatTime:

util.formatTime(new Date(log))
  我们可以尝试调用formatNumber(),是不是能够成功:

var n = util.formatNumber(1)

  成功了么?答案是不是定的,而且控制台报了这样的毛病:util.formatNumber is not a function;at "pages/logs/logs" page lifeCycleMethod onLoad function

  这是为何?答案就在这里:

module.exports = {
  formatTime: formatTime
}
  有幸的是笔者在这之前接触过php的第3方框架thinkPhp,里面正好有类似的代码。这个有甚么用呢?简单来讲就是让你这里的方法公然给其他类使用,我们可以看到这里我们只公然了formatTime方法(第1个是我们取的方法名,第2个是util.js中需要公然的方法名),如果我们把formatNumber()方法也公然了,就不会出现上面的毛病了:

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
}
  现在简单说说这几行代码的意思:传入1个date参数,然后使用date的方法获得年月日时分秒,返回这个时间点的格式化内容。格式化方法是这个:

[year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
  将年月日放进数组,并用map遍历,获得格式化的日期,formatNumber就是格式化的方法。formatNumber中获得到n为时间,将它字符串转换,然后检查这个字符串是单是双,由n[1]就能够判断单双,由于如果是单只有n[0],如果是双就是n[0][1]。所以判断出单双后,如果是单添加1个0到数字前方,如果是双则直接返回。这样做的结果最简单的体现就是当为1,则会返回01;如果是10则返回10。

  以后有1个join('/')方法,这个最直观的从界面上就能够判断出在数组每项后面加上/,并且在最后1个下标的值疏忽不实现,这样我们就能够取得我们常常看到的年月日格式2017/01/10。在后面的时分秒也是同理。

  基本上logs.js也看完了,接下来分析logs.json。在这里有1些内容,其实不是全空的:

{
    "navigationBarTitleText": "查看启动日志"
}

  记得在app.json中也有个参数叫做navigationBarTitleText:

"navigationBarTitleText": "WeChat",

  我们在这里一样写了这个东西有甚么用呢?很简单直接把我们的标题改变了呗:

  由此我们得到1个结论,子类的配置文件json修改相同参数,优先显示子类的json配置,然后再显示父类的。固然,可以应证1下原理,我们在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英文是块,所以说这个就是1块1块的意思。我们记得{{}}中的是js中的变量,所以logs是1个数组。在这里为了显示数组数据,微信誉的是wx:for这个语句。这倒是像我们写for int i = 0;i < count;i++的循环语句。wx:for-item获得到的应当是数组每个值,而"log"则被赋予了这个值的别名,我们用log就可以代表数组中的值。wx:key="*this"很晦涩难懂,在这里我们感觉是1个毫无相干的东西,因此完全不能乱猜,这里我们最好的解决方案:查找官方文档。

  文档内容:

wx:key

如果列表中项目的位置会动态改变或有新的项目添加到列表中,并且希望列表中的项目保持自己的特点和状态(如 <input/> 中的输入内容,<switch/> 的选中状态),需要使用 wx:key 来指定列表中项目的唯1的标识符。

wx:key 的值以两种情势提供

  1. 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯1的字符串或数字,且不能动态改变。
  2. 保存关键字 *this 代表在 for 循环中的 item 本身,这类表示需要 item 本身是1个唯1的字符串或数字,如:

当数据改变触发渲染层重新渲染的时候,会校订带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持本身的状态,并且提高列表渲染时的效力。

如不提供 wx:key,会报1个 warning, 如果明确知道该列表是静态,或没必要关注其顺序,可以选择疏忽。

  文档中所述最简单的解释在这里就是*this指的是数组中的item本身,而且在静态数组中有了这个值提高了渲染效力。这个参数暂时在这里不深入研究,笔者也只是略懂了点皮毛,技术有限请体谅。

  这里还有1个奇异的参数index,这个应当是默许生成给开发者调用下标用的,我们用就是了。

  在这里我们还是没有清楚block的用法,最简单的还是得结合图看:

  我们通过block的方法,取得了1个列表,所以不用想,block就是1行1行的数据,它的用法就是将内容以块来显示,然后批量使用。在这里我们block中只有text,所以暂时看不出block的强大,我们再加1个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中的内容为1块内容,我们创建出了1个列表。在以后的开发中,我相信大家会使用更多的block,实践出真知,大家会越用越熟练的。

  最后的1个wxss文件我就不加论述了,样式这个东西除练还是练,希望笔者与大家1起进步,早日练到应用自若。自此,全部demo全部研究透彻,作为微信小程序开发学习,我们要学以致用,从学习及第1反3,祝大家早日开发出自己的小程序!

生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生