wxml
wxml(WeiXin Markup Language)作为小程序前端的结构语言,和html类似,但是有以下几项需要注意:
- 属性是大小写区分的;
- 标签必须是严格闭合,否则编译报错;
- 属性值可以动态改变,使用
{{name}}
表示,但是该变量也是大小写区分的,并且必须用双引号括起来; - 没有被定义的变量的或者是被设置为 undefined 的变量不会被同步到 wxml 中;
- 如果一个组件需要控制渲染多个
view
时可以用一个block
来囊括,相当于html中的template
;
赋值
js文件里 Page 实例中修改data的时候,方法如下:
this.data.nameArray = [];
this.setData({
nameArray: this.data.nameArray
})
之所以要使用 setData
方法,是为了达到将数据从逻辑层传递到渲染层,在对比JS对象的前后差异,把差异应用到Dom树上,渲染出新的UI界面。
setData
方法是Page实例的原型函数,该操作是一个异步操作,第二个参数是一个callback回调,是这次 setData
对界面渲染完成后触发的回调函数。
逻辑语法
{{}}
该括号中,除了可以直接填写变量名之后,还可以使用三元运算符,或者是简单的数字运算,或者是字符串的拼接等操作。
条件逻辑
wx:if
/ wx:elif
/ wx:else
组成了条件判断的使用情况,具体例子如下:
<block wx:if="{{total > 10}}">
<view> view1 </view>
<view> view2 </view>
</block>
<view wx:elif="{{total > 5}}">
view 3
</view>
<view wx:else>
view 4
</view>
列表渲染
wx:for
/ wx:for-index
/ wx:for-item
/ wx:key
组成了列表渲染的组件,默认数组的当前项的下标变量名默认为 index ,数组当前项的变量名默认为 item,并且 wx:for-index
可以重命名当前循环的下标名(index),wx:for-item
可以重命名当前循环的元素(item),具体例子如下:
<view wx:for="{{names}}" wx:for-index="indexNewName" wx:for-item="itemNewName">
{{indexNewName}}: {{itemNewName}}
</view>
如果列表数据有新增或减少,或者是列表里元素的数据有变化时,为了达到动态渲染的效果,这时候可以使用 wx:key
来标识每一个渲染。wx:key
有两种形式提供:
- 字符串: 代表在for循环中的 array 的某个 property ,该属性需要保证是列表中唯一的字符串或数字,且不能动态改变;
- this: 保留关键字this代表在for循环中的item本身,这种表示需要保证item是一个唯一的字符串或者数字
举例如下:
<!-- 字符串: 列表里item中的一个唯一属性 -->
<switch wx:for="{{objectArray}}" wx:key="uniqueProperty" > {{item.uniqueProperty}}: {{item.otherProperty}} </switch>
<!-- this: 列表里item是一个唯一的字符串或者是数字 -->
<switch wx:for="{{numberArray}}" wx:key="*this" > {{item}} </switch>
模版
在wxml中可以使用 template 来定义模版,并用 name 属性来表示模版名字,在真正需要使用并渲染该模版的时候,就用 is 来表示使用的是哪一个模版,并且使用 data 来表示传入到该模版的渲染数据,具体例子如下:
<!-- 模版定义内容 -->
<template name="tmpl_1">
<view> {{id}}: {{name}}</view>
</template>
<!-- 实例化渲染使用模版, item = {id: 1, name: 'js'} -->
<template is="tmpl_1" data="{{...item}}"/>
引用
wxml提供了两种引用方法: import / include。两种方式使用的场景不同
- import 适用于引入上面提到的模版定义内容,但是该方法不能嵌套引入;
-
include 适用于将目标文件内容(除了
<template/>
/<wxs/>
),拷贝到引入的位置处
使用方法如下:
<!-- 使用 import -->
<import src="tmpl.wxml"/>
<!-- 使用 include -->
<include src="header.wxml"/>
共同属性
共同属性指的是: 所有wxml标签都支持属性。包括: id / class / style / hidden(Boolean) / data-* / bind* / catch*.
- hidden 是一个Boolean值,表示组件是否显示,默认显示
- data-* 自定义属性(任何类型),组件上触发的事件时,会发送给事件处理函数
- bind* / catch* 组件的事件
wxss
wxss(WeiXin Style Sheets),小程序的样式语言。
包括三种样式:
- 项目公共样式,也即是项目根目录下的 app.wxss 文件,该样式默认应用到所有页面;
- 页面样式,也即是每个页面同目录下,且与页面名一样的 {pageName}.wxss 文件,该样式默认应用到该页面样式;
- 其他样式,也就是在在根目录下用户新建一个目录,用于存放其他的样式文件,该样式文件要使用,需要用于引用才生效。
其他样式的引用方法如下两种:
@import url('../../otherss/common.wxss')
@import '../../otherss/bar.wxss'
选择器样式优先级
!important > sytle="" > #id > .class > element
微信提供了官方样式库 WeUI.wxss
js
小程序中的js由三部分组成: ECMAScript + 小程序框架 + 小程序API
小程序可以将任何一个js文件作为一个模块,通过 modules.exports 或者 exports 对外暴露接口。
例如如下代码:
// moduleA.js
module.exports = function (value) {
console.log(value);
}
// test.js
var printfunc = require('./moduleA');
printfunc('Hello world.')
小程序中js的执行顺序是: 先执行根目录下 app.js 中的内容,如果该文件中有 require 引入其他的js文件,那么也要根据引入的顺序来加载执行;然后按照 app.json 中定义的 pages 的顺序,逐一执行。
小程序中js变量的作用域,是只在本文件中有效的。不同的文件中可以声明和相同的变量和函数,不会互相影响。
小程序中其他js文件如果想要使用全局变量 app.js 中 App 实例里定义的变量,可以在文件中使用 var globalData = getApp();
来获取全局参数。
小程序的每个page页面里的逻辑层
每个页面的逻辑层都是一个 Page 实例,该实例包括如下内容:
Page({
// 内容
});
- 页面的初始数据:
data: {}
- 生命周期函数 - 监听页面加载:
onLoad: function (options) {}
- 生命周期函数 - 监听页面显示:
onShow: function () {}
- 生命周期函数 - 监听页面初次渲染完成:
onReady: function () {}
- 生命周期函数 - 监听页面隐藏:
onHide: function () {}
- 生命周期函数 - 监听页面卸载:
onUnload: functioin () {}
- 页面相关事件处理函数 - 监听用户下拉动作:
onPullDownRefresh: function () {}
- 页面上拉触底事件的处理函数:
onReachBottom: function () {}
,可以作为分页请求的入口 - 用户点击右上角分享:
onShareAppMessage: function () {}
- 用户滚动滚动条函数:
onPageScroll: function () {}
初次进入到页面,会触发 onLoad
/ onShow
/ onReady
事件;
如果触发了右上角的分享功能,那么页面会触发 onShareAppMessage
和 onHide
事件,等待分享对话框关闭之后,会触发 onShow
事件;
下拉刷新页面的时候,会触发 onPullDownRefresh
事件;
离开该页面会触发 onUnload
事件
注意: Page实例中的data属性里的数据value不要设为 undefined,不然会引起意想不到的bug.
onShareAppMessage
中的返回值里可以设置分享的一些属性,比如:title
/path
等,这样用户在通过该分享连接进来的时候,就会携带这些参数进来。
页面路由
- 使用
wx.navigateTo({url: pageD})
表示往当前页面栈中多推入一个页面D - 使用
wx.navigateBack()
表示退出当前页面栈最顶端的一个页面 - 使用
wx.redirectTo({url: pageE})
表示替换当前页为页面E,当页面栈总数为10无法再新增页面时,就是使用该redirectTo
API来进行页面跳转 - 使用
wx.switchTab({url: pageF})
表示清空当前的页面栈里的页面(除了tabBar中pageF前面的页面不会清空),页面栈为 [pageF],切换到tabBar中pageF前面的页面时,例如pageA时,不会触发pageA的 onLaunch 生命周期函数 - 使用
wx.reLaunch({url: pageF})
表示重启小程序,并且进入到pageF的页面,页面栈为 [pageF]
注意:
wx.navigateTo
和wx.redirectTo
只能打开非tabBar页面,而wx.switchTab
只能打开tabBar页面。
API
小程序提供的API按照功能分为: 网络、媒体、文件、数据缓存、位置、设备、界面和界面节点信息。API的调用一般有如下约定:
- wx.on* 开头的API是监听某个事件发生的API接口,接受一个callback函数作为参数。当该事件触发时,会调用callback函数。
- 多数API接口为异步接口,都接受一个Object作为参数。
- API的Object参数一般由 success / fail / complete 三个回调来接受接口调用结果。
- wx.get* 开头的API是获取宿主环境数据的接口。
- wx.set* 开头的API是写入数据到宿主环境的接口。
事件
在小程序里,事件指的是:“用户在渲染层的行为反馈”以及“组件的部分状态反馈”抽象成渲染层传递给逻辑层的事件。
事件绑定和冒泡捕获
事件绑定的写法和组件属性一致,以key="value"的形式,其中:
- key以bind或者catch开头,然后跟上事件的类型,如:bindtap/catchtouchstart。自基本库1.5.0起,bind和catch后可以紧跟冒号,其含义不变,如: bind:tap/catch:touchstart。同时bind和catch前面还可以加上 capture- 来表示事件的捕获阶段,没有的话表示事件的冒泡阶段。
- value是一个字符串,需要在对应的页面Page构造器中定义同名的函数,否则触发事件时,在控制台有报错信息。
bind事件绑定不会组织冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡。capture-catch
将中断捕获阶段并取消冒泡阶段。
其他组件的自定义事件,如无特别说明,都是非冒泡事件,如 <form/> 的submit事件,<input/>的input事件,<scroll-view/>的scroll事件
补充:说明一下事件冒泡和捕获。
"DOM2级事件"规定的事件流包含三个阶段:事件捕获、处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,然后是实际的目标接收到事件,最后阶段是冒泡阶段。
兼容
通过API wx.getSystemInfoSync()
可以获取到系统和小程序基础库版本信息 SDKVersion,该参数在开发环境的工程配置文件 project.config.json 中的配置项 libVersion。
网友评论