我们在开始微信小程序开发的时候,对JS,HTML等前端知识一无所知,完完全全就是门外汉在尝试一个新的方向。

在下载好开发工具,微信就已经提供了一个DEMO例子:

从程序开发的角度来看这个陌生的目录结构,pages是存放页面的,utils是存放工具类的,而app开头的三个文件既然放在根目录级别,那么按理讲,应该是和配置有关。

我们看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函数用于注册一个小程序,onLanuch用于处理小程序的初始化,当小程序初始化完成的时候会调用一次。

onLanuch这里的处理是取出wx中的log,然后再把当前日期添加进去。

wx是一个命名空间,相当于一个库,它有很多公共方法。

我们这里的操作和Android中使用SP(SharePreferences)是差不多的,wx有个本地缓存,这个缓存可以根据相关的key值取出对应的内容。这里有个有趣的语法:|| [],在javascript中,表示如果这个变量如果是undefined,null,NAN,false,0中的任意一种,就设置为一个空的数组,可以理解为?:的用法。然后调用javascript的unshift方法,把当前日期插入数组的第一个元素。

getUserInfo是自定义的函数,传入一个函数作为参数,而且这里还定义了全局对象globalData,它有一个字段userInfo,初始值为null,通过判断userInfo是否为空,非空则在cb为函数类型的情况下调用cb,空的情况下,则通过调用wx.login方法,在success的情况下调用wx的getUserInfo获取userInfo。

这个js文件已经大概的展示了javascript的很多基本语法,因为javascript是动态语言,它是面向函数语言,因此和java这种面向对象语言在语义实现上,差别相当大,我们可以简单的理解为java操作的是对象,而javascript操作的是函数,而wx.login中的参数就是一个对象,因此用{}包起来,函数其实也是一个对象,所以它后面同样也有{},这个对象就是loginObject,在它success的时候调用wx.getUserInfo函数。

无论是面向对象还是面向函数,本质上都是体现开发人员理解问题的思路,只是语义实现上不同而已,毕竟javascript和java要解决的问题所在的领域有着相当大的差异。

我们再看看app.json这个文件:

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

根据文档的解释,这个文件是对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多tab等。

pages用于设置页面的路径,是一个数组,我们这个DEMO的页面只有两个:index和logs,其中第一个元素,index,是小程序的第一个页面,每次新增或者删除某个页面,都要在这里进行修改。

window用来设置默认的窗口的属性,显然app.json是设置整个小程序窗口的默认属性,会被具体页面的相关属性覆盖。

最后是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;
}

这个文件其实就是CSS文件,不过微信自己本身做了一些处理,这个文件的内容就是设置了container这个节点视图的公共属性。

从这三个根目录的文件,我们也大概知道一个小程序的页面的组成结构,但是还少了一个文件,那就是页面视图的文件。

DEMO的logs页面就包含了四个文件:.json,.js,.wxss和.wxml。

我们看一下logs.wxml这个文件:

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

<view/>表示一个视图的节点,相当于Android中的ViewGroup,然后通过class赋予这个view一个或多个类名,wxss就是通过这个class来控制对应视图的渲染效果,这里是两个类名:container和log-list,目的就是在一些属性上覆盖.container的设置。

<block/>表示这是一个多节点的视图,也就是列表组件,通过wx:for表示这个列表组件的数组来源,在微信的设计中,{{}}表示数据绑定,这里绑定了logs这个数组作为数据来源。

wx:for-item指定了当前数组的元素名,我们可以理解为java中的增强for的用法:for(item : array)。

wx:key表示一个唯一标识,因为这个数组是动态数组,会不断增加自己本身的长度,而我们不希望已经创建好的元素在重新渲染的时候会被修改,因此通过wx:key指定*this,表示for循环中的item只是被重新排序,而不是被重新创建,这样是为了提高渲染的效率。

最后我们看一下<block/>里面的子视图,是一个text视图,渲染的内容是数组中的元素,默认数组的下标变量名是index,元素名称是item,因此{{index + 1}}表示取当前元素的下标,因为下标是从0开始,所以这里加1来和人类世界中下标从1开始的共识达成一致,而log就是logs中的元素的内容,因为我们已经通过wx:for-item指定了item的名称为log。

logs目录下的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))
})
})
}
})

util.js是我们utils目录的文件,这里的"../../utils/util.js"是通过相对路径来导入这个js文件,按照我们的理解,相当于import一个库。

Page函数是用来注册一个页面,data声明页面的初始数据,这里是一个logs数组,而data里面的数据是通过json传递到页面,因此这里面的格式要确保完全符合json格式。然后调用onLoad函数,在加载页面的时候通过setData将逻辑层的数据传递到视图层,也就是所谓的数据绑定,并且改变this.data的内容。

setData中的函数通过调用数组的map函数,将数组的内容重新映射成新的内容,这里相当于初始化数组,map就是用来对数组内容进行赋值的。

我们看一下util.js的内容:

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
}

这里的内容很简单,就是对log的日期进行格式化,不过我们注意到最后的内容,module.exports执行了赋值操作。

这个其实是和require搭配的,require返回的就是这个module.exports,然后定义了一个formatTime对象,也就是可以调用的对象,而这个对象就是formatTime函数。

通过require和module.exports来确定了这个js文件暴露出来的API。

我们现在来关注一个很重要的语法:=和:这两个操作符到底是怎么用的。

=就是赋值操作符,这个毋庸置疑,而:其实也是赋值操作,对于a:function,其实表示key值为a的value的内容为function,所以formatTime:formatTime就是表示util.formatTime这个属性对应的是formatTime函数。

我们再来看一下index目录下的文件。

先看一下index.js:

//index.js
//获取应用实例
var app = getApp()
Page({
data: {
motto: 'Hell 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
})
})
}
})

我们通过getApp函数来获取小程序实例,因为我们需要调用app.js中的函数,这里调用的是getUserInfo,可以理解为app.js中定义的方法都是公共方法,因为这里并没有require和module.exports的调用。

这里有一个新的知识点:bindViewTap。

这个是一个事件处理函数,事件是逻辑层到视图层的通讯方式,将用户的行为反馈到逻辑层进行处理,bindViewTap这个事件函数是用户在点击时候触发的,相当于onClick,wx.navigateTo表示跳转到url指定的页面。

我们看一下inde.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>

要通过bindtap指定点击事件函数。

事件分为两种:冒泡事件和非冒泡事件,冒泡事件会把事件往上传递,而非冒泡则反之。冒泡事件前缀是bind,而非冒泡事件是catch。

通过对这个DEMO,我们大概了解到小程序的目录结构,和一些相关的基础知识,后面会在具体的开发工作中继续补充相关的知识。

微信小程序官方DEMO解读的更多相关文章

  1. 微信小程序官方demo学习

    最近微信小程序很火,很喜欢那种轻应用,用完就走的理念.于是,下载好微信开发者工具,学习一下官方demo. 体验下来,有类似react和vue的感觉,dom类似react那种组件的,data-bindi ...

  2. 03——微信小程序官方demo讲解——page部分

    一个page由一个文件夹以及文件夹下四个文件组成. 比如一个页面叫index.则需要在pages目录下新建一个index目录,且包含由index+类型(js\wxml\wxss\json)为名组成的若 ...

  3. 02——微信小程序官方demo讲解——app部分

    第一节讲了目录结构,这节主要讲解下目录中app.js部分. 它由三部分组成app.js.app.json与app.wxss 1.JS部分 1.1概述 //app.js App({ onLaunch: ...

  4. 01——微信小程序官方demo讲解——文件结构

    1.环境概览 首先环境配置的部分略过,打开小程序开发工具.选择一个空目录,即可开始一个demo项目. 其中新建成功后的目录如图所示: 2.文件结构描述 如图所示,左边是界面展示,右边是目录结构. 目录 ...

  5. 【福利】微信小程序精选Demo合集

    小编最近在开发小程序,也读到了不少优秀的小程序源码,项目中有些需求可以直接从源码里粘贴复制过来,虽然这样做不利于自己独立编写代码,但比较是给公司做项目啊,秉着效率第一的原则,简直没有什么比ctrl+c ...

  6. 微信小程序开源Demo精选

    来自:http://www.jianshu.com/p/0ecf5aba79e1 文/weapphome(简书作者)原文链接:http://www.jianshu.com/p/0ecf5aba79e1 ...

  7. Mac上微信小程序官方开发工具卡死的问题

    Mac上微信小程序官方开发工具打开后卡死,无法操作,也关不掉,解决方案: 三步: 1.在应用中删除“微信web开发者工具” 2.删除一下几个配置和缓存文件: 1.-/Library/Applicati ...

  8. weapp微信小程序初探demo

    https://github.com/donglegend/weapp-demo 参考文档开发工具安装微信weapp API git项目源码微信小程序 demo效果展示效果预览

  9. 微信小程序(组件demo)以及预览方法:(小程序交流群:604788754)

    1. 获取微信小程序的 AppID 登录 https://mp.weixin.qq.com ,就可以在网站的"设置"-"开发者设置"中,查看到微信小程序的 Ap ...

随机推荐

  1. HDU 4463 Outlets 【最小生成树】

    <题目链接> 题目大意: 给你一些点的坐标,要求你将这些点全部连起来,但是必须要包含某一条特殊的边,问你连起这些点的总最短距离是多少. 解题分析: 因为一定要包含那条边,我们就记录下那条边 ...

  2. 超出JavaScript安全整数限制的数字计算-BigInt

    JavaScript中的基本数据类Number是双精度浮点数,它可以表示的最大安全范围是正负9007199254740991,也就是2的53次方减一,在浏览器控制台分别输入Number.MAX_SAF ...

  3. vue-cli@3.x初体验之前篇-回顾vue-cli@2.x创建项目的流程

    模拟实际工作中的操作,假如新开启了一个vue项目,可以先看看上篇博文中的git操作,新建空仓库vue-demo,并拉取到本地,创建本地dev分支后 1. 全局安装vue-cli yarn global ...

  4. Linux 系统分级及root权限相关

    单用户模式修改用户密码 救援模式 让我们先来了解一下linux的运行步骤 1. Linux系统引导的顺序掌握Linux系统引导的顺序:BIOSMBRKernelinit其中,BIOS的工作是检查计算机 ...

  5. C# LnkHelper

    using System; using System.Collections.Generic; using System.Text; using Microsoft.Win32; using Syst ...

  6. 图片预览组件PhotoView

    图片预览组件PhotoView PhotoView是一款图片预览组件,广泛应用于大图的查看.该组件支持图片手势缩放.旋转等功能.它可以很好的和ViewPager.Picasso等组件结合,实现各种复杂 ...

  7. 在UnrealEngine中用Custom节点实现高斯模糊

    3x3高斯模糊 //input sW 分辨率宽 //input sH 分辨率高 //input NotUse 为了开启SceneTextureLookup函数而连接的节点,但是不参与逻辑 //inpu ...

  8. Scrapy基础(十三)————ItemLoader的简单使用

    ItemLoader的简单使用:目的是解决在爬虫文件中代码结构杂乱,无序,可读性差的缺点 经过之前的基础,我们可以爬取一些不用登录,没有Ajax的,等等其他的简单的爬虫回顾我们的代码,是不是有点冗长, ...

  9. [ZJOI2016]大森林

    Description: 小Y家里有一个大森林,里面有n棵树,编号从1到n 0 l r 表示将第 l 棵树到第 r 棵树的生长节点下面长出一个子节点,子节点的标号为上一个 0 号操作叶子标号加 1(例 ...

  10. 2017.07.10【NOIP提高组】模拟赛B组

    Summary 今天题目总体不是难,但是分数很低,只有100+10+30,其中第二题还是以前做过的,第一题设计数论,而且以前做过同一个类型的题目,比赛推了很长时间.第三题时以前做过的原题,是贪心没学好 ...