小程序学习笔记(一)
小程序与普通网页的开发
- 小程序的逻辑层和视图层是分开的。
- 小程序提供了自己的视图层描述语言 WXML 和 WXSS,以及基于 JavaScript 的逻辑层框架,并在视图层与逻辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑。
代码构成
JSON 配置
1. app.json
常用的app配置
{
// 页面路径列表,每一项都对应一个页面的 路径(含文件名) 信息。文件名不需要写文件后缀,框架会自动去寻找对应位置的 .json, .ts, .wxml, .less 四个文件进行处理。
"pages": [
"pages/index/index",
"pages/logs/index"
],
// 全局的默认窗口表现,用于设置小程序的状态栏、导航条、标题、窗口背景色。
"window": {
"navigationBarTitleText": "Demo"
},
// 底部 tab 栏的表现,其中 list 接受一个数组,只能配置最少 2 个、最多 5 个 tab。
"tabBar": {
"list": [{
"pagePath": "pages/index/index",
"text": "首页"
}, {
"pagePath": "pages/logs/index",
"text": "日志"
}]
},
// 网络超时时间,单位均为毫秒。
"networkTimeout": {
"request": 10000,
"downloadFile": 10000
},
// 是否开启 debug 模式,默认关闭。调试信息以 info 的形式给出,其信息有 Page 的注册,页面路由,数据更新,事件触发等。
"debug": true
}
2. 页面配置
每一个小程序页面也可以使用同名 .json 文件来对本页面的窗口表现进行配置,页面中配置项会覆盖 app.json 的 window 中相同的配置项。
完整配置项说明请参考小程序页面配置
3. sitemap 配置
用来配置小程序及其页面是否允许被微信索引。
完整配置项说明请参考小程序 sitemap 配置
注:sitemap 的索引提示是默认开启的,如需要关闭 sitemap 的索引提示,可在小程序项目配置文件 project.config.json 的 setting 中配置字段 checkSiteMap 为 false。
框架
场景值
1. 介绍
场景值用来描述用户进入小程序的路径。一个场景值代表一种进入小程序的路径。
完整场景值的含义请查看场景值列表
2. 获取
对于小程序,可以在 App 的 onLaunch 和 onShow,或wx.getLaunchOptionsSync 中获取上述场景值。
逻辑层
1. 介绍
逻辑层将数据进行处理后发送给视图层,同时接受视图层的事件反馈。
注意:小程序框架的逻辑层并非运行在浏览器中,因此 JavaScript 在 web 中一些能力都无法使用,如 window,document 等。
2. 注册小程序
使用App()注册小程序实例,App() 必须在 app.js 中调用,必须调用且只能调用一次,不然会出现无法预期的后果。
详细的参数含义和使用请参考 App 参考文档
注册实例常用的监听函数
// app.js
App({
onLaunch (options) {
// 生命周期回调——监听小程序初始化,全局只触发一次
},
onShow (options) {
// 生命周期回调——监听小程序启动或切前台
},
onHide () {
// 生命周期回调——监听小程序切后台
},
onError (msg) {
// 错误监听函数
console.log(msg)
},
globalData: 'I am global data'
})
整个小程序只有一个 App 实例,是全部页面共享的。开发者可以通过 getApp 方法获取到全局唯一的 App 实例,获取App上的数据或调用开发者注册在 App 上的函数。
// xxx.js
const appInstance = getApp()
console.log(appInstance.globalData) // I am global data
3. 注册页面
每个页面,都需要在页面对应的 js 文件中进行注册,指定页面的初始数据、生命周期回调、事件处理函数等。
- 简单的页面可以使用 Page() 进行构造。详细的参数含义和使用请参考 Page 参考文档
Page 注册页面
//index.js
Page({
data: {
text: "This is page data."
},
onLoad: function(options) {
// 页面创建时执行
},
onShow: function() {
// 页面出现在前台时执行
},
onReady: function() {
// 页面首次渲染完毕时执行
},
onHide: function() {
// 页面从前台变为后台时执行
},
onUnload: function() {
// 页面销毁时执行
},
onPullDownRefresh: function() {
// 触发下拉刷新时执行
},
onReachBottom: function() {
// 页面触底时执行
},
onShareAppMessage: function () {
// 页面被用户分享时执行
},
onPageScroll: function() {
// 页面滚动时执行
},
onResize: function() {
// 页面尺寸变化时执行
},
onTabItemTap(item) {
// tab 点击时执行
console.log(item.index)
console.log(item.pagePath)
console.log(item.text)
},
// 事件响应函数
viewTap: function() {
this.setData({
text: 'Set some data for updating view.'
}, function() {
// this is setData callback
})
},
// 自由数据
customData: {
hi: 'MINA'
}
})
Component 注册页面
Component({
data: {
text: "This is page data."
},
methods: {
onLoad: function(options) {
// 页面创建时执行
},
onPullDownRefresh: function() {
// 下拉刷新时执行
},
// 事件响应函数
viewTap: function() {
// ...
}
}
})
behaviors 用法
// my-behavior.js
module.exports = Behavior({
data: {
sharedText: 'This is a piece of data shared between pages.'
},
methods: {
sharedMethod: function() {
this.data.sharedText === 'This is a piece of data shared between pages.'
}
}
})
// page-a.js
var myBehavior = require('./my-behavior.js')
Page({
behaviors: [myBehavior],
onLoad: function() {
this.data.sharedText === 'This is a piece of data shared between pages.'
}
})
4. 生命周期
5. 页面路由
- 采用栈的思想控制页面路由
6. 模块化
- 可以将一些公共的代码抽离成为一个单独的 js 文件,作为一个模块。模块只有通过 module.exports 或者 exports 才能对外暴露接口(推荐使用 module.exports)。
- 小程序目前不支持直接引入 node_modules , 开发者需要使用到 node_modules 时候建议拷贝出相关的代码到小程序的目录中,或者使用小程序支持的 npm 功能。
视图层
1. 介绍
框架的视图层由 WXML(WeiXin Markup language) 与 WXSS(WeiXin Style Sheet) 编写,由组件来进行展示。
2. WXML
-
数据绑定
标题 内容 示例 内容 使用双大括号将变量包起来 <view> {{ message }} </view>
组件属性 需要在双引号之内 <view id="item-{{id}}"> </view>
控制属性 需要在双引号之内 <view wx:if="{{condition}}"> </view>
关键字 需要在双引号之内 <checkbox checked="{{false}}"> </checkbox>
三元运算 可以在 {{}} 内进行简单的运算 <view hidden="{{flag ? true : false}}"> Hidden </view>
算数运算 可以在 {{}} 内进行简单的运算 <view> {{a + b}} + {{c}} + d </view>
逻辑判断 可以在 {{}} 内进行简单的运算 <view wx:if="{{length > 5}}"> </view>
字符串运算 可以在 {{}} 内进行简单的运算 <view>{{"hello" + name}}</view>
数据路径运算 可以在 {{}} 内进行简单的运算 <view>{{object.key}} {{array[0]}}</view>
数组 可以在 {{}} 内直接进行组合 <view wx:for="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view>
对象 可以在 {{}} 内直接进行组合 <template is="objectCombine" data="{{for: a, bar: b}}"></template>
-
列表渲染
标题 内容 示例 wx:for 默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item。 <view wx:for="{{array}}">{{index}}: {{item.message}}</view>
wx:for 使用 wx:for-item 可以指定数组当前元素的变量名,使用 wx:for-index 可以指定数组当前下标的变量名。 <view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">{{idx}}: {{itemName.message}}</view>
block wx:for 渲染一个包含多节点的结构块 <block wx:for="{{[1, 2, 3]}}"><view> {{index}}: </view><view> {{item}} </view></block>
wx:key 指定列表中项目的唯一的标识符。如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。 wx:key 的值以两种形式提供:1. 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是唯一的。 <switch wx:for="{{objectArray}}" wx:key="unique" style="display: block;"> {{item.id}} </switch>
2. 保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字。<switch wx:for="{{numberArray}}" wx:key="*this" style="display: block;"> {{item}} </switch>
-
条件渲染
标题 内容 示例 wx:if 判断是否需要渲染该代码块,也可以用 wx:elif
和wx:else
来添加一个 else 块。<view wx:if="{{length > 5}}"> 1 </view><view wx:elif="{{length > 2}}"> 2 </view><view wx:else> 3 </view>
block wx:if 一次性判断多个组件标签 <block wx:if="{{true}}"><view> view1 </view><view> view2 </view></block>
【注意】:
<block/>
并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。wx:if vs hidden
- wx:if:在切换时组件会销毁和重新渲染。
- hidden:组件始终会渲染,只是简单的控制显示与隐藏。
- 一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。
-
模板
定义模板:使用name属性,作为模板的名字。点击查看代码
<!-- index: int msg: string time: string --> <template name="msgItem"> <view> <text> {{index}}: {{msg}} </text> <text> Time: {{time}} </text> </view> </template>
使用模板:使用 is 属性,声明需要的使用的模板,然后将模板所需要的 data 传入。is 属性可以使用 Mustache 语法,来动态决定具体需要渲染哪个模板。
点击查看代码
<template is="msgItem" data="{{...item}}"/> <block wx:for="{{[1, 2, 3, 4, 5]}}"> <template is="{{item % 2 == 0 ? 'even' : 'odd'}}"/> </block>
模板的作用域:模板拥有自己的作用域,只能使用 data 传入的数据以及模板定义文件中定义的
<wxs />
模块。 -
引用
import
可以在该文件中使用目标文件定义的template
。include
可以将目标文件除了<template/>
<wxs/>
外的整个代码引入,相当于是拷贝到include
位置。
组件
视图容器
1. page-container
页面容器。用于在页面内进行复杂的界面设计(比如在页面中弹出半屏的弹窗,在页面内夹在一个全屏的子页面等),用户进行返回操作会直接离开当前页面,不符合用户预期,预期应为关闭当前弹出的组件。 为此提供“假页”容器组件,效果类似于 popup 弹出层,页面内存在该容器时,当用户进行返回操作,关闭该容器不关闭页面。返回操作包括三种情形,右滑手势、安卓物理返回键和调用 navigateBack 接口。
2. view
视图容器。