小程序的主要开发语言是 JavaScript,jq等js库无法在小程序中运行。
一、框架 .json 后缀的 JSON 配置文件 .wxml 后缀的 WXML 模板文件,静态配置 .wxss 后缀的 WXSS 样式文件 .js 后缀的 JS 脚本逻辑文件1. JSON配置 根目录的app.json 和 project.config.json,每个页面(pages/index)page.json。 app.json:全局配置,小程序的所有页面路径(第一项默认为首页) 、界面表现、网络超时时间、底部 tab等。 project.config.json:针对微信开发者工具
这个软件的个性化配置。2. WXML 组件:, , , <map>等。 逻辑: ``, wx:if
等。 样式WXSS。 JS逻辑 3. 运行框架 生成页面顺序:page.json ==> page.wxml + page.wxss ==> page.js
1
2
3
4
5
6
7
8
9
// page.js
Page ({
data : { // 参与页面渲染的数据
logs : []
},
onLoad : function () {
// 页面渲染后 执行
}})
// Page()是个页面构造器(相当于类)
二、协同工作 小程序开发成员:运营者、开发者、数据分析者。 运营数据查看:小程序管理后台 和 小程序数据助手(也是一个小程序)。
三、WXML模板 数据绑定( js 与 wxml ) 1
2
3
4
5
6
7
8
9
// 动态绑定
// 1. wxml
< text data - test = " {{test}} " > hello world < /text >
// 2. js
Page ({
data : {
test : ( new Date ()). toString ()
},
})
没有被定义的变量的或者是被设置为 undefined 的变量不会被同步到 wxml 中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<block wx:if= "{{true}}" >
<view> view1 </view>
<view> view2 </view>
</block>
// 列表渲染
<!-- array 是一个数组 -->
<view wx:for= "{{array}}" >
{{index}}: {{item.message}}
</view>
<!-- 对应的脚本文件
Page({
data: {
array: [{
message: 'foo',
}, {
message: 'bar'
}]
}
})
-->
wx:for-item, wx:for-index
模板 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<template name= "msgItem" >
<view>
<text> {{index}}: {{msg}} </text>
<text> Time: {{time}} </text>
</view>
</template>
<!-- is可以动态决定具体需要渲染哪个模板 -->
<block wx:for= "{{[1, 2, 3, 4, 5]}}" >
<template is= "{{item % 2 == 0 ? 'even' : 'msgItem'}}" />
</block>
<import src= "item.wxml" />
<template is= "item" data= "{{text: 'forbar'}}" />
<!-- include -->
<!-- index.wxml -->
<include src= "header.wxml" />
<view> body </view>
<include src= "footer.wxml" />
<!-- header.wxml -->
<view> header </view>
<!-- footer.wxml -->
<view> footer </view>
wxml标签共同属性 四、WXSS 两种wxss:app.wxss(根目录)和page.wxss(每个页面的wxss)
样式的引用 1
2
@import url('./test_0.css')
@ import './test_0.wxss'
用rpx
。 动态的内联样式 1
2
3
4
5
6
7
8
9
<!--index.wxml-->
<!--可动态变化的内联样式-->
<!--
{
eleColor: 'red',
eleFontsize: '48rpx'
}
-->
<view style= "color: {{eleColor}}; font-size: {{eleFontsize}}" ></view>
官方样式库 五、JavaScript脚本
模块化 小程序中可以将任何一个JavaScript 文件作为一个模块,通过module.exports 或者 exports 对外暴露接口。 作用域 在文件中声明的变量和函数只在该文件中有效,不同的文件中可以声明相同名字的变量和函数,不会互相影响。 当需要使用全局变量的时,通过使用全局函数 getApp() 获取全局的实例,并设置相关属性值,来达到设置全局变量的目的 1
2
3
// 访问全局变量
var global = getApp ()
console . log ( global . globalValue ) // 输出 globalValue
六、程序(代码层面的小程序) 1. 程序构造器App() 在app.js
里 其他js里:getApp()
构造器: 1
2
3
4
5
6
7
App ({
onLaunch : function ( options ) {},
onShow : function ( options ) {},
onHide : function () {},
onError : function ( msg ) {},
globalData : ' I am global data '
})
小程序的JS脚本是运行在同一个JsCore的线程里,小程序的每个页面各自有一个WebView线程进行渲染,所以小程序切换页面时,小程序逻辑层的JS脚本运行上下文依旧在同一个JsCore线程中。所有页面的脚本逻辑都跑在同一个JsCore线程,页面使用setTimeout或者setInterval的定时器,然后跳转到其他页面时,这些定时器并没有被清除,需要开发者自己在页面离开的时候进行清理。2. 页面(界面、配置和逻辑) 一个页面,wxml、js必须,json、wxss可选,都在同一文件夹下。 根目录 ==> App.js ==> App() ; 每个页面目录 ==> page.js ==> Page()。 1
2
3
4
5
6
7
8
9
10
11
12
Page ({
data : { text : " This is page data. " },
onLoad : function ( options ) { },
onReady : function () { },
onShow : function () { },
onHide : function () { },
onUnload : function () { },
onPullDownRefresh : function () { },
onReachBottom : function () { },
onShareAppMessage : function () { },
onPageScroll : function () { }
})
点击商品列表页的项目进入商品详情页:
1
2
3
4
5
6
7
8
9
// pages/list/list.js 表示商品详情页
// 列表页使用navigateTo跳转到详情页
wx . navigateTo ({ url : ' pages/detail/detail?id=1&other=abc ' })
// pages/detail/detail.js
Page ({
onLoad : function ( option ) { console . log ( option . id ) console . log ( option . other )
}
})
// onLoad里的函数有个option参数,就是来接收来自其他页面的数据的
和网页URL一样,页面URL上的value如果涉及特殊字符(例如:&字符、?字符、中文字符等 ),需要采用UrlEncode后再拼接到页面URL上: 'pages/detail/detail?id=1&other=abc'
。
setData() 1
2
3
4
5
6
7
8
9
10
// page.js
Page ({
onLoad : function (){
this . setData ({
text : ' change data '
}, function (){
// 在这次setData对界面渲染完毕后触发
})
}
})
小程序宿主环境提供了四个和页面相关的用户行为回调: 1)下拉刷新 onPullDownRefresh 监听用户下拉刷新事件,需要在app.json的window选项中或页面配置page.json中设置enablePullDownRefresh为true。{"enablePullDownRefresh": true }。
当处理完数据刷新后,wx.stopPullDownRefresh可以停止当前页面的下拉刷新。 2)上拉触底 onReachBottom 监听用户上拉触底事件。可以在app.json的window选项中或页面配置page.json中设置触发距离onReachBottomDistance。在触发距离内滑动期间,本事件只会被触发一次。当界面的下方距离页面底部距离小于100像素时触发回调:page.json: {"onReachBottomDistance": 100 }
。 3)页面滚动 onPageScroll 监听用户滑动页面事件,参数为 Object,包含 scrollTop 字段,表示页面在垂直方向已滚动的距离(单位px)。 4)用户转发 onShareAppMessage 只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮,在用户点击转发按钮的时候会调用,此事件需要return一个Object,包含title和path两个字段,用于自定义转发内容。 1
2
3
4
5
6
7
8
9
// page.js
Page ({
onShareAppMessage : function () {
return {
title : ' 自定义转发标题 ' ,
path : ' /page/user?id=123 '
}
}
})
页面栈[ pageA, pageB, pageC ],其中pageA在最底下,pageC在最顶上,也就是用户所看到的界面 wx.navigateTo
推入一个新的页面,wx.redirectTo({ url: 'pageE' })
是替换当前页变成pageE。
1
2
3
4
5
6
7
8
9
10
// app.json定义小程序原生底部tab
{
" tabBar " : {
" list " : [
{ " text " : " Tab1 " , " pagePath " : " pageA " },
{ " text " : " Tab1 " , " pagePath " : " pageF " },
{ " text " : " Tab1 " , " pagePath " : " pageG " }
]
}
}
每个tab对应一个页面栈,使用wx.switchTab({ url: 'pageF' })
,此时原来的页面栈会被清空,然后会切到pageF所在的tab页面,页面栈变成 [ pageF ],但是如果切回原来的tab页面,该页面的onLoad不会被触发。 wx.navigateTo和wx.redirectTo只能打开非TabBar页面,wx.switchTab只能打开Tabbar页面。 还可以使用 wx. reLaunch({ url: ‘pageH’ }) 重启小程序,并且打开pageH,此时页面栈为 [ pageH ]。
scroll-view组件
wx
对象实际上就是小程序的宿主环境所提供的全局对象,几乎所有小程序的API都挂载在wx
对象底下(除了Page/App
等特殊的构造器)。 几大功能API:网络、媒体、文件、数据缓存、位置、设备、界面、界面节点信息还有一些特殊的开放接口。
wx.on*:监听。 API接口,异步,参数为一个对象,对象有success、fail、complete三个回调函数。 wx.get*:获取宿主环境数据。 wx.set*:写入数据到宿主环境。 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
wx . request ({
url : ' test.php ' ,
data : {},
header : { ' content-type ' : ' application/json ' },
success : function ( res ) {
// 收到https服务成功后返回
console . log ( res . data )
},
fail : function () {
// 发生网络错误等情况触发
},
complete : function () {
// 成功或者失败后触发
}
})
事件 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 触发顺序:4-2-3-1 -->
<view
id= "outer"
bind:touchstart= "handleTap1"
capture-bind:touchstart= "handleTap2"
>
outer view
<view
id= "inner"
bind:touchstart= "handleTap3"
capture-bind:touchstart= "handleTap4"
>
inner view
</view>
</view>
catch事件绑定可以阻止冒泡事件向上冒泡: 将handleTap2的capture-bind改为capture-catch,将只触发handleTap2(capture-catch将中断捕获阶段和取消冒泡阶段),handleTap4, handleTap3, handleTap1不会被触发。 自定义事件如无特殊声明都是非冒泡事件,如<form/>的submit事件, 的input事件, 的scroll事件。