小程序包含一个描述整体程序的 和多个描述各自页面的 。
描述页面的四个文件必须具有相同的路径与文件名
网页者需要面对的环境是各式各样的浏览器, 端需要面对 、、浏览器等,在端需要面对、以及 、 系统中的各式 。而小程序过程中需要面对的是两大操作系统 和 的微信客户端,以及用于辅助的小程序者工具,小程序中三大运行环境也是有所区别的,
是一种数据格式,并不是编程语言,在小程序中,扮演的静态配置的角色。
我们可以看到在项目的根目录有一个 和 ,此外在 目录下还有一个 ,我们依次来说明一下它们的用途。
是当前小程序的全局配置,包括了小程序的所有页面路径、界面表现、网络超时时间、底部 等。 项目里边的 配置内容如下:
通常大家在使用一个工具的时候,都会针对各自喜好做一些个性化配置,例如界面颜色、编译配置等等,当你换了另外一台电脑重新安装工具的时候,你还要重新配置。
考虑到这点,小程序者工具在每个项目的根目录都会生成一个 ,你在工具上做的任何配置都会写入到这个文件,当你重新安装工具或者换电脑工作时,你只要载入同一个项目的代码包,者工具就自动会帮你恢复到当时你项目时的个性化配置,其中会包括编辑器的颜色、代码上传时自动压缩等等一系列选项。
因此我们提供了 ,让者可以定义每个页面的一些属性,例如刚刚说的顶部颜色、是否允许下拉刷新等等
这里说一下小程序里配置的一些注意事项。
文件都是被包裹在一个大括中 {},通过-的方式来表达数据。的必须包裹在一个双引中,在实践中,编写 的时候,忘了给 值加双引或者是把双引写成单引是常见错误。
的值只能是以下几种数据格式,其他任何格式都会触发报错,例如 中的 。
数字,包含浮点数和整数
字符串,需要包裹在双引中
值, 或者
数组,需要包裹在方括中 []
对象,需要包裹在大括中 {}
还需要注意的是 文件中无法使用注释,试图添加注释将会引发报错
要换一个思路了,在框架,其他的中,在中的标签,现在都叫
组件了,要记得转换过来。所谓封装好的组件,在使用的时候就已经有了
一些,交互的功能了。而标签更多的还只是语义化
标签名字有点不一样
往往写 的时候,经常会用到的标签是 , , ,者在写一个页面的时候可以根据这些基础的标签组合出不一样的组件,例如日历、弹窗等等。换个思路,既然大家都需要这些组件,为什么我们不能把这些常用的组件包装起来,大大提高我们的效率。
从上边的例子可以看到,小程序的 用的标签是 , , 等等,这些标签就是小程序给者包装好的基本能力,我们还提供了地图、视频、音频等等组件能力。
多了一些 这样的属性以及 这样的表达式
在网页的一般流程中,我们通常会通过 操作 (对应 的描述产生的树),以引起界面的一些变化响应用户的行为。例如,用户点击某个按钮的时候, 会记录一些状态到 变量里边,同时通过 操控 的属性或者行为,进而引起界面一些变化。当项目越来越大的时候,你的代码会充斥着非常多的界面交互逻辑和程序的各种状态变量,显然这不是一个很好的模式,因此就有了 的模式(例如 , ),提倡把渲染和逻辑分离。简单来说就是不要再让 直接操控 , 只需要管理状态即可,然后再通过一种模板语法来描述状态和界面结构的关系即可。
小程序的框架也是用到了这个思路,如果你需要把一个 的字符串显示在界面上。
是这么写 :
具有 大部分的特性,小程序在 也做了一些扩充和修改。
新增了尺寸单位。在写 样式时,者需要考虑到手机设备的屏幕会有不同的宽度和设备像素比,采用一些技巧来换算一些像素单位。 在底层支持新的尺寸单位 ,者可以免去换算的烦恼,只要交给小程序底层来换算即可,由于换算采用的浮点数运算,所以运算结果会和预期结果有一点点偏差。
提供了全局的样式和局部样式。和前边 , 的概念相同,你可以写一个 作为全局样式,会作用于当前小程序的所有页面,局部页面样式 仅对当前页面生效。
此外 仅支持部分 选择器
我们改变数据必须用吗? .({: })
而且这个还必须在函数里面
响应用户的操作就是这么简单,更详细的事件可以参考文档 - 事件 。
此外你还可以在 中调用小程序提供的丰富的 ,利用这些 可以很方便的调起微信提供的能力,例如获取用户信息、本地存储、微信支付等。在前边的 例子中,在 就调用了 . 获取微信用户的头像和昵称,最后通过 把获取到的信息显示到界面上。更多 可以参考文档 小程序的 。
这些得自己看官方文档的内容
微信客户端在打开小程序之前,会把整个小程序的代码包下载到本地。
紧接着通过 的 字段就可以知道你当前小程序的所有页面路径:
于是微信客户端就把首页的代码装载进来,通过小程序底层的一些机制,就可以渲染出这个首页。
小程序启动之后,在 定义的 实例的 回调会被执行:
整个小程序只有一个 实例,是全部页面共享的,更多的事件回调参考文档 注册程序 。
是一个页面构造器,这个构造器就生成了一个页面。在生成页面的时候,小程序框架会把 数据和 一起渲染出最终的结构,于是就得到了你看到的小程序的样子。
在渲染完界面之后,页面实例就会收到一个 的回调,你可以在这个回调处理你的逻辑。
有关于 构造器更多详细的文档参考 注册页面
小程序提供了丰富的基础组件给者,者可以像搭积木一样,组合各种组件拼合成自己的小程序。
要获取用户的地理位置时,只需要:
相比于 ,格式最大的优点是易于人的阅读和编写,通常不需要特殊的工具,就能读懂和修改,是一种轻量级的数据交换格式。
文件都是被包裹在一个大括中 {},通过-的方式来表达数据。
看起来同 的对象表达方式十分相似,但是有所不同。
报错信息的箭头附近是有语法错误的
全称是 ,是小程序框架设计的一套标签语言,结合小程序的基础组件、事件系统,可以构建出页面的结构。
使用 : 和 : 来添加一个 块:
因为 : 是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 标签将多个组件包装起来,并在上边使用 : 控制属性。
在组件上使用 : 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。默认数组的当前项的下标变量名默认为 ,数组当前项的变量名默认为
使用 :- 指定数组当前元素的变量名,使用 :- 指定数组当前下标的变量名:
就是说指定他们的变量名,不是叫和了
,也可以将 用在 标签上,以渲染一个包含多节点的结构块。例如:
难道不放在里就不能渲染多个标签了吗
提供模板(),可以在模板中定义代码片段,然后在不同的地方调用。使用 属性,作为模板的名字。然后在 内定义代码片段,如:
这个东西我以前还百度过
看例子还是有点看不懂
但好像也少用 知道他是模板就好了
就重复代码段,到时候用到再百度
提供两种文件引用方式和。
可以在该文件中使用目标文件定义的 ,
需要注意的是 有作用域的概念,即只会 目标文件中定义的 ,而不会 目标文件中 的 ,简言之就是 不具有递归的特性。
例如: 引用 , 引用,在中可以使用定义的 ,在中可以使用定义的 ,但是不能使用定义的 ,
( )是一套用于小程序的样式语言,用于描述的组件样式,也就是视觉上的效果。
在小程序中,者不需要像那样去优化样式文件的请求数量,只需要考虑代码的组织即可。样式文件最终会被编译优化,具体的编译原理我们留在后面章节再做介绍。
为了减轻者样式的工作量,我们提供了.基础样式库。
是一套与微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信内网页和微信小程序量身设计,令用户的使用感知更加统一。包含、、、、、、、等各式原生。
小程序的主要语言是 ,者使用 来业务逻辑以及调用小程序的 来完成业务需求。
小程序中的 是由 以及小程序框架和小程序 来实现的。同浏览器中的 相比没有 以及 对象,所以类似 、这种浏览器类库是无法在小程序中运行起来的,同样的缺少 模块和包管理的机制,小程序中无法加载原生库,也无法直接使用大部分的 包。
小程序目前可以运行在三大平台:
平台,包括9、10、11
平台
小程序
小程序提供语法转码工具帮助者,将 6代码转为 5代码,从而在所有的环境都能得到很好的执行
者需要在项目设置中,勾选 6 转 5 开启此功能。
浏览器中,所有 是在运行在同一个作用域下的,定义的参数或者方法可以被后续加载的脚本访问或者改写。同浏览器不同,小程序中可以将任何一个 文件作为一个模块,通过. 或者 对外暴露接口。(6提出的模块化)
请看是一个简单模块示例,. 引用模块,并使用暴露的2方法完成一个变量乘以 2 的操作。
浏览器中,脚本严格按照加载的顺序执行
而在小程序中的脚本执行顺序有所不同。小程序的执行的入口文件是 . 。并且会根据其中 的模块顺序决定文件的运行顺序,
当 . 执行结束后,小程序会按照者在 . 中定义的 的顺序,逐一执行。
就是说会先执行,.中的代码
然后才会执行页面中的代码
当需要使用全局变量的时,通过使用全局函数 () 获取全局的实例,并设置相关属性值,来达到设置全局变量的目的
从这个例子我们可以看到3个点:
1.渲染层和数据相关。
2.逻辑层负责产生、处理数据。
3.逻辑层通过 实例的 方法传递数据到渲染层。
1. 程序构造器()
宿主环境提供了 () 构造器用来注册一个程序,需要留意的是() 构造器必须写在项目根目录的.里,实例是单例对象,在其他脚本中可以使用宿主环境提供的 () 来获取程序实例。
这是应用的生命周期:页面有页面的生命周期
代码清单3-4 构造器
2. 程序的生命周期和打开场景
初次进入小程序的时候,微信客户端初始化好宿主环境,同时从网络下载或者从本地缓存中拿到小程序的代码包,把它注入到宿主环境,初始化完毕后,微信客户端就会给实例派发事件,构造器参数所定义的方被调用。
进入小程序之后,用户可以点击右上角的关闭,或者按手机设备的键离开小程序,此时小程序并没有被直接销毁,我们把这种情况称为“小程序进入后台状态”,构造器参数所定义的方被调用。
当再次回到微信或者再次打开小程序时,微信客户端会把“后台”的小程序唤醒,我们把这种情况称为“小程序进入前台状态”,构造器参数所定义的方被调用。
我们可以看到,的生命周期是由微信客户端根据用户操作主动触发的。为了避免程序上的混乱,我们不应该从其他代码里主动调用实例的生命周期函数。
在微信客户端中打开小程序有很多途径:从群聊会话里打开,从小程序列表中打开,通过微信扫一扫二维码打开,从另外一个小程序打开当前小程序等,针对不同途径的打开方式,小程序有时需要做不同的业务处理,所以微信客户端会把打开方式带给和的调用参数,示例代码以及详细参数如代码清单3-5和表3-2所示。需要留意小程序的宿主环境在迭代更新过程会增加不少打开场景,因此要获取最新的场景值说明请查看官方文档:
()得到.里面的实例
通过以上可以看出,与的主要区别是:
()方法只运行一次,也就是说当达到设定的时间后就出发运行指定的代码,运行完后就结束了,如果还想再次执行同样的函数,可以在函数体内再次调用(),可以达到循环调用的效果。
()是循环执行的,即每达到指定的时间间隔就执行相应的函数或者表达式,是真正的定时器。
与此同时,我们要特别留意一点,所有页面的脚本逻辑都跑在同一个线程,页面使用或者的定时器,然后跳转到其他页面时,这些定时器并没有被清除,需要者自己在页面离开的时候进行清理。
2. 页面构造器()
宿主环境提供了 () 构造器用来注册一个小程序页面,()在页面脚本.中调用,() 的调用方式如代码清单3-8所示。构造器接受一个参数,参数说明如表3-4所示,其中属性是当前页面模板中可以用来做数据绑定的初始数据,我们会在后文展开讨论; / / / / 5个回调是实例的生命周期函数,我们在后文展开; / / / 4个回调是页面的用户行为,我们也会在后文展开。
代码清单3-8 构造器
3. 页面的生命周期和打开参数
页面初次加载的时候,微信客户端就会给实例派发事件,构造器参数所定义的方被调用,在页面没被销毁之前只会触发1次,在的回调中,可以获取当前页面所调用的打开参数,关于打开参数我们放在这一节的最后再展开阐述。
页面显示之后,构造器参数所定义的方被调用,一般从别的页面返回到当前页面时,当前页的方法都会被调用。
在页面初次渲染完成时,构造器参数所定义的方被调用,在页面没被销毁前只会触发1次,触发时,表示页面已经准备妥当,在逻辑层就可以和视图层进行交互了。
以上三个事件触发的时机是早于 ,早于。
页面不可见时,构造器参数所定义的方被调用,这种情况会在使用.切换到其他页面、底部切换时触发。
当前页面使用.或.返回到其他页时,当前页面会被微信客户端销毁回收,此时构造器参数所定义的方被调用。
在列表页打开商品详情页时把商品的传递过来,详情页通过刚刚说的回调的参数就可以拿到商品,从而绘制出对应的商品,
宿主环境所提供的实例的原型中有函数,我们可以在实例下的方法调用.把数据传递给渲染层,从而达到更新界面的目的。
由于小程序的渲染层和逻辑层分别在两个线程中运行,所以传递数据实际是一个异步的过程,
所以的第二个参数是一个回调,在这次对界面渲染完毕后触发。
其一般调用格式是 (, ),其中是由多个: 构成的对象。
代码清单3-11 使用更新渲染层数据
此外需要注意以下3点:
直接修改 实例的. 而不调用 . 是无法改变页面的状态的,还会造成数据不一致。
由于是需要两个线程的一些通信消耗,为了提高性能,每次设置的数据不应超过1024。
不要把中的任意一项的设为,否则可能会有引起一些不可预料的。
5. 页面的用户行为
小程序宿主环境提供了四个和页面相关的用户行为回调:
下拉刷新
监听用户下拉刷新事件,需要在.的选项中或页面配置.中设置为。当处理完数据刷新后,.可以停止当前页面的下拉刷新。
上拉触底
监听用户上拉触底事件。可以在.的选项中或页面配置.中设置触发距离。在触发距离内滑动期间,本事件只会被触发一次。
页面滚动
监听用户滑动页面事件,参数为 ,包含 字段,表示页面在垂直方向已滚动的距离(单位)。
用户转发
只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮,在用户点击转发按钮的时候会调用,此事件需要一个,包含和两个字段,用于自定义转发内容,如代码清单3-13所示。
需要注意,所有组件名和属性都是小写,多个单词会以英文横杠 "-" 进行连接。
对于一些容器组件,其内容可以在其开始标签和结束标签之间。
这个属性只要组件有吗
(中文名模式)
我们介绍一下一般调用的约定:
. 开头的 是监听某个事件发生的接口,接受一个 函数作为参数。当该事件触发时,会调用 函数。
如未特殊约定,多数 接口为异步接口 ,都接受一个作为参数。
的参数一般由、、三个回调来接收接口调用结果,示例代码如代码清单3-17所示,详细说明如表3-9所示。
. 开头的是获取宿主环境数据的接口。
. 开头的是写入数据到宿主环境的接口。
事件是通过这个属性绑定在组件上的,同时在当前页面的构造器中定义对应的事件处理函数,当用户点击该区域时,达到触发条件生成事件,该事件处理函数会被执行,同时还会收到一个事件对象。