概述
微信小程序是微信官方推出的以微信客户端为宿主的类web程序。其优点在于不需要用户手动下载app本体,仅通过服务器传输即可完成大部分普通App能够做到的事情,并且本身体积较小,即开即用,极大提高了用户的使用积极性,是现代应用的创新实践
小程序代码构成
一个完整的小程序页面一般包括以下四部分:
JSON配置文件
WXML模板文件
WXSS样式文件
JS文件
如果有过uni-app使用经验的话就能很快上手微信小程序,即便没有也没关系,其逻辑和web应用实际上相差不是很大,新手也可快速上手成为一名小程序开发者
JSON配置文件
一般创建新的小程序项目会有两个地方存在JSON配置文件:app.json和页面的JSON文件
app.json
app.json 是当前小程序的全局配置,包括了小程序的所有页面路径、界面表现、网络超时时间、底部 tab 等,初始项目的app.json配置如下
{
"pages":[
"pages/index/index",
"pages/logs/logs"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "Weixin",
"navigationBarTextStyle":"black"
}
}
pages字段 —— 用于描述当前小程序所有页面路径,这是为了让微信客户端知道当前你的小程序页面定义在哪个目录;
window字段 —— 定义小程序所有页面的顶部背景颜色,文字颜色定义等
其他配置项细节可以参考文档 小程序的配置 app.json
页面配置 page.json
这里的 page.json 是用于配置单个页面的全局设置,其配置会覆盖app.json配置文件,从而达到页面自定义风格的效果
其他配置项细节可以参考文档 页面配置
WXML 结构
如下示例为创建小程序时的初始wxml代码
<view class="container">
<view class="userinfo">
<button wx:if="{{!hasUserInfo && canIUse}}"> 获取头像昵称 </button>
<block wx:else>
<image src="{{userInfo.avatarUrl}}" background-size="cover"></image>
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
</block>
</view>
<view class="usermotto">
<text class="user-motto">{{motto}}</text>
</view>
</view>
类似于uni-app,微信小程序自封装了一些标签导致与html标签的不同,并且使用类似于vue的指令来控制数据的渲染,以下为其基本使用方式
数据绑定
通过使用 {{}} 符号将data对象内的数据响应式渲染到插值符号中来达成渲染数据的效果
<view> {{message}} </view>
// page.js
// 此为 js 文件内容,在 Page 函数内定义数据和函数
Page({
data: {
message: 'Hello MINA!'
}
})
列表渲染
在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。
默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item
<view wx:for="{{array}}">
{{index}}: {{item.message}}
</view>
Page({
data: {
array: [{
message: 'foo',
}, {
message: 'bar'
}]
}
})
使用 wx:for-item 可以指定数组当前元素的变量名,使用 wx:for-index 可以指定数组当前下标的变量名
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
{{idx}}: {{itemName.message}}
</view>
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 input 中的输入内容, switch 的选中状态),需要使用 wx:key 来指定列表中项目的唯一的标识符
如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略
条件渲染
在wxml中,使用 wx:if="" 来判断是否需要渲染该代码块,当表达式的内容为true时才会渲染
<view wx:if="{{condition}}"> True </view>
也可以用 wx:elif 和 wx:else 来添加一个 else 块
<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>
wx:if 与 hidden的区别
因为 wx:if 之中的模板也可能包含数据绑定,所以当 wx:if 的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。
同时 wx:if 也是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。
相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。
一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。
template模板
WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用
为需要使用的template定义一个名称
<template name="msgItem">
<view>
<text> {{index}}: {{msg}} </text>
<text> Time: {{time}} </text>
</view>
</template>
使用时就可在template标签上填入is的属性值,然后按需填入模板所需的数据
<template is="msgItem" data="{{...item}}"/>
Page({
data: {
item: {
index: 0,
msg: 'this is a template',
time: '2016-09-15'
}
}
})
注:模板拥有自己的作用域,只能使用 data 传入的数据以及模板定义文件中定义的 <wxs /> 模块
import和include
import
import可以在该文件中使用目标文件定义的template
<!-- item.wxml -->
<template name="item">
<text>{{text}}</text>
</template>
<!-- 引入 item.wxml 文件中的内容 -->
<import src="item.wxml"/>
<template is="item" data="{{text: 'forbar'}}"/>
注:import 有作用域的概念,只引用中直接引入的template,而不会引入间接import内的template。如:C import B,B import A,在 C 中可以使用 B 定义的template,在 B 中可以使用 A 定义的template,但是 C 不能使用 A 定义的template
wxss样式
整体使用和web端的css差不太多,不过有几点要注意下:
定义在 app.wxss 中的样式为全局样式,作用于每一个页面。在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器;
使用@import语句可以导入外联样式表,@import后跟需要导入的外联样式表的相对路径,用;表示语句结束,如下所示
/** app.wxss **/
@import "common.wxss";
.middle-p {
padding:15px;
}
wxs模块
概述
WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构
WXS 与 JavaScript 是不同的语言,有自己的语法,并不和 JavaScript 一致
WXS 代码可以编写在 wxml 文件中的 <wxs> 标签内,或以 .wxs 为后缀名的文件内
在微信开发者工具里面,右键可以直接创建 .wxs 文件,在其中直接编写 WXS 脚本
模块
每一个 .wxs 文件和 <wxs> 标签都是一个单独的模块。
每个模块都有自己独立的作用域。即在一个模块里面定义的变量与函数,默认为私有的,对其他模块不可见。一个模块要想对外暴露其内部的私有变量与函数,只能通过 module.exports 实现
var foo = "'hello world' from comm.wxs";
var bar = function(d) {
return d;
}
module.exports = {
foo: foo,
bar: bar
};
上述例子在 /pages/comm.wxs 的文件里面编写了 WXS 代码。该 .wxs 文件可以被其他的 .wxs 文件 或 WXML 中的 <wxs> 标签引用
module 对象
每个 wxs 模块均有一个内置的 module 对象,提供基本的exports和require功能
// 导出数据
module.exports = {
FOO: 'foo',
bar: 'bar',
};
module.exports.msg = "some msg";
// 导入数据
var tools = require("./tools.wxs");
<!-- 通过 wxs 标签调用 -->
<wxs src="./../logic.wxs" module="logic" />
注:module 属性是当前 <wxs> 标签的模块名。在单个 wxml 文件内,建议其值唯一。有重复模块名则按照先后顺序覆盖(后者覆盖前者)。不同文件之间的 wxs 模块名不会相互覆盖
引用的时候,要注意如下几点:
只能引用 .wxs 文件模块,且必须使用相对路径。
wxs 模块均为单例,wxs 模块在第一次被引用时,会自动初始化为单例对象。多个页面,多个地方,多次引用,使用的都是同一个 wxs 模块对象。
如果一个 wxs 模块在定义之后,一直没有被引用,则该模块不会被解析与运行