一个小程序页面由四个文件组成,分别是:
文件类型 | 必需 | 作用 |
---|---|---|
js | 是 | 页面逻辑 |
wxml | 是 | 页面结构 |
json | 否 | 页面配置 |
wxss | 否 | 页面样式表 |
注意:为了方便开发者减少配置项,描述页面的四个文件必须具有相同的路径与文件名
允许上传的文件
在项目目录中,以下文件会经过编译,因此上传之后无法直接访问到:.js、app.json、.wxml、*.wxss(其中 wxml 和 wxss 文件仅针对在 app.json 中配置了的页面)。除此之外,只有后缀名在白名单内的文件可以被上传,不在白名单列表内文件在开发工具能被访问到,但无法被上传。具体白名单列表如下:
- wxs
- png
- jpg
- jpeg
- gif
- svg
- json
- cer
- mp3
- aac
- m4a
- mp4
- wav
- ogg
- silk
目录结构
小程序包含一个描述整体程序的 app
和多个描述各自页面的 page
。
一个小程序主体部分由三个文件组成,必须放在项目的根目录,如下:
文件 | 必需 | 作用 |
---|---|---|
app.js | 是 | 小程序逻辑 |
app.json | 是 | 小程序公共配置 |
app.wxss | 否 | 小程序公共样式表 |
小程序配置 app.json
app.json
是当前小程序的全局配置,包括了小程序的所有页面路径、界面表现、网络超时时间、底部 tab 等
app.json
配置内容如下:
{
//页面路径列表
"pages": [
"pages/index/index",
"pages/logs/index"
],
//全局的默认窗口表现
"window": {
//导航栏样式,仅支持以下值:default 默认样式、custom 自定义导航栏
"backgroundTextStyle": "light",
//顶部背景色,仅支持十六进制颜色
"navigationBarBackgroundColor": "#fff",
//导航栏标题文字内容
"navigationBarTitleText": "极客教程",
//导航栏标题颜色,仅支持 black / white
"navigationBarTextStyle": "black",
//根据项目需求决定下面几个内容是否添加
//窗口的背景色
"backgroundColor":"#ffffff",
//下拉 loading 的样式,仅支持 dark / light
"backgroundTextStyle":"light",
//顶部窗口的背景色,仅 iOS 支持
"backgroundColorTop":"#ffffff",
//底部窗口的背景色,仅 iOS 支持
"backgroundColorBottom":"#ffffff",
//是否开启全局的下拉刷新
"enablePullDownRefresh":"false",
//页面上拉触底事件触发时距页面底部距离,单位为px
"onReachBottomDistance":"50px",
//屏幕旋转设置,支持 auto / portrait / landscape
"pageOrientation":"auto"
},
//底部tab栏的表现
"tabBar": {
// list接受一个数组,只能配置最少 2 个、最多 5 个 tab
"list": [{
//页面路径
"pagePath": "pages/index/index",
//tab上按钮文字
"text": "首页"
//图片路径,icon 大小限制为40kb,不支持网络图片,当 postion 为 top 时,不显示 icon
"iconPath": "pages/imges/1.png",
//选中时的图片路径,icon 大小限制为40kb,不支持网络图片,当 postion 为 top 时,不显示 icon
"selectedIconPath": "pages/imges/1.png",
}, {
"pagePath": "pages/logs/logs",
"text": "日志"
"iconPath": "pages/imges/2.png",
"selectedIconPath": "pages/imges/2.png",
}]
},
//设置网络超时时间
"networkTimeout": {
//request的超时时间,单位:毫秒
//涉及request内容设置
"request": 10000,
//downloadFile的超时时间,单位:毫秒
//涉及download内容设置
"downloadFile": 10000,
//connectSocket的超时时间,单位:毫秒
//涉及Socket内容设置
"connectSocket":10000,
//uploadFile的超时时间,单位:毫秒
//涉及upload内容设置
"uploadFile":10000
},
//是否开启 debug 模式,默认关闭
"debug": true
}
配置项
属性 类型 必填 描述 最低版本
pages string[] 是 页面路径列表
window Object 否 全局的默认窗口表现
tabBar Object 否 底部 tab 栏的表现
networkTimeout Object 否 网络超时时间
debug boolean 否 是否开启 debug 模式,默认关闭
functionalPages boolean 否 是否启用插件功能页,默认关闭 2.1.0
subpackages Object[] 否 分包结构配置 1.7.3
workers string 否 Worker 代码放置的目录 1.9.90
requiredBackgroundModes string[] 否 需要在后台使用的能力,如「音乐播放」
plugins Object 否 使用到的插件 1.9.6
preloadRule Object 否 分包预下载规则 2.3.0
resizable boolean 否 iPad 小程序是否支持屏幕旋转,默认关闭 2.3.0
navigateToMiniProgramAppIdList string[] 否 需要跳转的小程序列表,详见 wx.navigateToMiniProgram 2.4.0
usingComponents Object 否 全局自定义组件配置 开发者工具 1.02.1810190
permission Object 否 小程序接口权限相关设置 微信客户端 7.0.0
必须要有这个文件,没有也是会报错!
可以在这个文件中监听并处理小程序的生命周期函数、声明全局变量
JSON语法
JSON文件都是被包裹在一个大括号中 {},通过key-value的方式来表达数据。JSON的Key必须包裹在一个双引号中,忘了给 Key 值加双引号或者是把双引号写成单引号是常见错误。
JSON的值只能是以下几种数据格式,其他任何格式都会触发报错,例如 JavaScript 中的 undefined。
- 数字,包含浮点数和整数
- 字符串,需要包裹在双引号中
- Bool值,true 或者 false
- 数组,需要包裹在方括号中 []
- 对象,需要包裹在大括号中 {}
- Null
还需要注意的是 JSON 文件中无法使用注释,试图添加注释将会引发报错
app.wxss
这个文件不是必须的,只是个全局CSS样式文件
app.wxml
这个也不是必须的,而且这个并不是指主界面,小程序的主页面是靠在JSON文件中配置来决定的
有了这两个文件运行程序,IDE就不会报错了
WXML
WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构
数据绑定
<!--wxml-->
<view> {{message}} </view>
// page.js
Page({
data: {
message: 'Hello MINA!'
}
})
列表渲染
<!--wxml-->
<view wx:for="{{array}}"> {{item}} </view>
// page.js
Page({
data: {
array: [1, 2, 3, 4, 5]
}
})
条件渲染
<!--wxml-->
<view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
<view wx:elif="{{view == 'APP'}}"> APP </view>
<view wx:else="{{view == 'MINA'}}"> MINA </view>
// page.js
Page({
data: {
view: 'MINA'
}
})
模板
<!--wxml-->
<template name="staffName">
<view>
FirstName: {{firstName}}, LastName: {{lastName}}
</view>
</template>
<template is="staffName" data="{{...staffA}}"></template>
<template is="staffName" data="{{...staffB}}"></template>
<template is="staffName" data="{{...staffC}}"></template>
// page.js
Page({
data: {
staffA: {firstName: 'Hulk', lastName: 'Hu'},
staffB: {firstName: 'Shang', lastName: 'You'},
staffC: {firstName: 'Gideon', lastName: 'Lin'}
}
})
引用
WXML 提供两种文件引用方式import
和include
import
import
可以在该文件中使用目标文件定义的template
,如:
在 item.wxml 中定义了一个叫item
的template
:
<!-- item.wxml -->
<template name="item">
<text>{{text}}</text>
</template>
在 index.wxml 中引用了 item.wxml,就可以使用item
模板:
<import src="item.wxml"/>
<template is="item" data="{{text: 'forbar'}}"/>
import 的作用域
import 有作用域的概念,即只会 import 目标文件中定义的 template,而不会 import 目标文件 import 的 template
如:C import B,B import A,在C中可以使用B定义的template
,在B中可以使用A定义的template
,但是C不能使用A定义的template
<!-- A.wxml -->
<template name="A">
<text> A template </text>
</template>
<!-- B.wxml -->
<import src="a.wxml"/>
<template name="B">
<text> B template </text>
</template>
<!-- C.wxml -->
<import src="b.wxml"/>
<template is="A"/> <!-- Error! Can not use tempalte when not import A. -->
<template is="B"/>
include
include
可以将目标文件除了 <template/>
<wxs/>
外的整个代码引入,相当于是拷贝到 include
位置,如:
<!-- index.wxml -->
<include src="header.wxml"/>
<view> body </view>
<include src="footer.wxml"/>
<!-- header.wxml -->
<view> header </view>
<!-- footer.wxml -->
<view> footer </view>
WXSS
WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式
WXSS 用来决定 WXML 的组件应该怎么显示
WXSS 具有 CSS 大部分特性,WXSS 对 CSS 进行了扩充以及修改
与 CSS 相比,WXSS 扩展的特性有:
- 尺寸单位
- 样式导入
尺寸单位
- rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx
- 如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素
设备 | rpx换算px (屏幕宽度/750) | px换算rpx (750/屏幕宽度) |
---|---|---|
iPhone5 | 1rpx = 0.42px | 1px = 2.34rpx |
iPhone6 | 1rpx = 0.5px | 1px = 2rpx |
iPhone6 Plus | 1rpx = 0.552px | 1px = 1.81rpx |
建议: 开发微信小程序时设计师可以用 iPhone6 作为视觉稿的标准
注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况
样式导入
使用@import
语句可以导入外联样式表,@import
后跟需要导入的外联样式表的相对路径,用;
表示语句结束
示例代码:
/** common.wxss **/
.small-p {
padding:5px;
}
/** app.wxss **/
@import "common.wxss";
.middle-p {
padding:15px;
}
内联样式
框架组件上支持使用 style、class 属性来控制组件的样式。
- style:静态的样式统一写到 class 中。style 接收动态的样式,在运行时会进行解析,请尽量避免将静态的样式写进 style 中,以免影响渲染速度
<view style="color:{{color}};" />
- class:用于指定样式规则,其属性值是样式规则中类选择器名(样式类名)的集合,样式类名不需要带上
.
,样式类名之间用空格分隔。
<view class="normal_view" /
选择器
目前支持的选择器有:
选择器 | 样例 | 样例描述 |
---|---|---|
.class | .intro | 选择所有拥有 class="intro" 的组件 |
#id | #firstname | 选择拥有 id="firstname" 的组件 |
element | view | 选择所有 view 组件 |
element, element | view, checkbox | 选择所有文档的 view 组件和所有的 checkbox 组件 |
::after | view::after | 在 view 组件后边插入内容 |
::before | view::before | 在 view 组件前边插入内容 |
全局样式与局部样式
定义在 app.wxss 中的样式为全局样式,作用于每一个页面
在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器
WXS
WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML
,可以构建出页面的结构
注意
- WXS 不依赖于运行时的基础库版本,可以在所有版本的小程序中运行
- WXS 与 JavaScript 是不同的语言,有自己的语法,并不和 JavaScript 一致
- WXS 的运行环境和其他 JavaScript 代码是隔离的,WXS 中不能调用其他 JavaScript 文件中定义的函数,也不能调用小程序提供的API
- WXS 函数不能作为组件的事件回调
- 由于运行环境的差异,在 iOS 设备上小程序内的 WXS 会比 JavaScript 代码快 2 ~ 20 倍。在 android 设备上二者运行效率无差异
以下是一些使用 WXS 的简单示例
页面渲染
<!--wxml-->
<wxs module="m1">
var msg = "hello world";
module.exports.message = msg;
</wxs>
<view> {{m1.message}} </view>
页面输出:
hello world
数据处理
// page.js
Page({
data: {
array: [1, 2, 3, 4, 5, 1, 2, 3, 4]
}
})
<!--wxml-->
<!-- 下面的 getMax 函数,接受一个数组,且返回数组中最大的元素的值 -->
<wxs module="m1">
var getMax = function(array) {
var max = undefined;
for (var i = 0; i < array.length; ++i) {
max = max === undefined ?
array[i] :
(max >= array[i] ? max : array[i]);
}
return max;
}
module.exports.getMax = getMax;
</wxs>
<!-- 调用 wxs 里面的 getMax 函数,参数为 page.js 里面的 array -->
<view> {{m1.getMax(array)}} </view>
页面输出:
5
JS逻辑交互
一个服务仅仅只有界面展示是不够的,还需要和用户做交互:响应用户的点击、获取用户的位置等等
编写JS
脚本文件来处理用户的操作:
<view>{{ message}}</view>
<button bindtap="clickMe">点击我</button>
点击 button
按钮的时候,我们希望把界面上 message
显示成 "Hello World"
,于是我们在 button
上声明一个属性: bindtap
在 JS 文件里边声明了 clickMe
方法来响应这次点击操作:
Page({
clickMe() {
this.setData({message: 'Hello World'})
}
})
可以在 JS 中调用小程序提供的丰富的 API,利用这些 API 可以很方便的调起微信提供的能力
例如获取用户信息、本地存储、微信支付等