开发工具
- 小程序有专门的开发者工具(ide),代码编辑->本地调试->真机与看->发布
- 小程序的ide可以支持多段开发(小程序里还有钉钉?mppaas?)
框架
文件架构
- 项目分为app和page架构 app描述项目整体,page即页面文件夹
- app包含app.json(项目配置) app.js(逻辑) app.acss(样式)
- Page 包含.js(页面逻辑) .acss(页面样式) .axml(页面结构) .json(页面配置)
- 小程序运行时会将其所有打包为一份js,点开小程序时加载,离开时销毁
逻辑结构
- 小程序使用响应式的数据绑定系统,分为视图层和逻辑层,逻辑层变动,视图层改变
- 小程序的开发环境并非浏览器,故没有document和window的全局对象
- Js可以使用es6模块系统
Npm安装第三方模块
App
概述
- app代表顶层应用,管理全局和页面数据,提供钩子函数,同时它也是一个构造函数,一个小程序就是app构造出来的一个实例
- app.json 中pages参数(该应用所有页面级别的组件的路径注册)和window参数(窗口表现相关)
- app.acss 可选(全局样式)
- app.js 中onLaunch onShow onHide onError 等钩子函数(全局数据可放在里面)
App()
- App.js中通过app()来配置钩子函数
- onLaunch在小程序加载时触发一次
- onShow在后台进入前台和启动时触发
- onHide在前台进入后台时触发
- onError在js发生错误时触发
前台与后台: 其实是手机直接home离开时会进入,当进入后台时间较长或者系统资源占用过高时会销毁
- onLaunch和onShow中的参数options中只有两个参数query和path
- Query是启动参数的query字段解析而来
- Path是启动参数的page字段解析而来
getApp()
- getApp()可以获取到app实例,从而得到存储在app.js中的全局数据
- 不要在app()中调用getApp方法,this即可获得实例
- 不要在onLaunch方法中使用getCurrentPage(获取页面栈),当时页面还未生成
- 每个页面之间的js模块变量不会互相影响,各个脚本声明的变量和函数只对该文件有效
App.json
- App.json中
- 全局配置pages页面路径,
- window中设置窗口表现,
- tabBar的多tab应用(客户端窗口底部栏切换页面)
- Pages默认第一个为首页
- window中
- defaultTitle窗口标题
- pullRefresh 是否支持下拉刷新
- allBounceVertical 是否支持纵向拽啦超过实际内容
- titleBarColor 导航栏背景
page
简介
- Page是一个页面负责页面展示和交互 也是一个构造函数
- Page页面中需要重新渲染的话,需要调用setData方法
page()
- 每个页面中通过构造函数Page生成当前页面
- .js中page()的参数对象包括生命周期函数和事件处理函数还有页面初始数据
- 生命周期函数有
- onLoad(一次,加载时触发,query参数是my.navigateTo和my.redirectTo中传递的query对象)
- onReady(页面初次渲染完成,代表页面已经准备妥当,可以和视图进行交互,页面的设置my.setNavigationBar在onReady后设置)
- onShow(每次页面显示时触发)
- onHide(页面隐藏时触发)
- onUnload(页面卸载时触发)
- 事件处理函数
- onPullDownRefresh(app.json中window开启了pullRefresh可用,下拉刷新时调用)
- onShareAppMessage
- 生命周期函数有
setPage
- setPage改变逻辑层数据并传递到视图层,并改变page()中对象的data对象
- setPage的对象key很灵活,可以使用‘ary[0].name’:’newName’这种形式
- setPage可以使用回调函数,在页面渲染完成后触发
$spliceData
- 同setPage类似,将逻辑层数据发到视图层,并改变页面实例data数据
- 但是它在处理长列表数据有更好的性能
getCurrentPages
- 方法执行获得页面栈实例,以栈的顺序存储在一个数组中
小程序框架通过栈的形式维护页面,路由发生切换时,页面栈有不同表现
路由 | 页面栈 |
---|---|
路由初始化 | 新页面进栈 |
打开新页面 | 新页面进栈 |
重定向 | 当前页面出栈 新页面入栈 |
当前页面返回 | 当前页面出栈 |
Tab导航 | 所有页面出栈 新页面入栈 |
page.json
- 页面配置 只能配置window(会覆盖app.json中window属性中的配置项)
视图层
axml定义页面结构可以做到
数据绑定
- 分为文本绑定和属性绑定两种,{ {js表达式}}
- 比较特殊的是对象{ {name:’tzy’}}绑定的是对象{name:’tzy’}
条件渲染
- 属性分为控制属性和数据属性两种
- 标签属性上添加a:if a:elif a:else加上胡子表达式形成控制属性
- block可以包含多个节点,只接受控制属性
列表渲染
- 视图组件加上A:for属性的列表渲染,可以支持对绑定的数组各项进行重复渲染该组件
- 默认组件中可以使用的当前项变量名为item,可以通过a:key-item修改,当前项的索引为index,可以通过a:key-index修改
- 列表渲染支持block
A:key
- 属性是作为列表各项目的组件的唯一标识,当列表各项目是动态的,可以通过添加a:key来保持组件自己的特征和状态
- A:key的属性值可以是字符串(唯一)也可以是*this关键字(项目本身)
Key
其实更加常用
引用模板
- Axml支持template来定义模板代码片段,可以方便在不同地方复用,必须使用name属性作为标识
- 在其他地方使用is属性来使用,is属性支持胡子表达式
- Template拥有自己的作用域,只支持传入的data的属性
- 引用的时候可以用import,import也可以引入第三方的视图组件
- Include的引入方式会引入文件中除了template外的所有元素
事件
- 事件是视图层到逻辑层的通讯方式,可以将用户的行为反馈传递到逻辑层
- on(冒泡) catch(不冒泡) + 事件类型
- 事件类型默认传入事件对象,其中包含type(事件类型) timeStamp(事件触发时间戳) target(事件源) currentTarget(当前事件源)
- 事件类型不同,事件对象不同,基础的事件有以上属性,还有自定义事件(detail),touch事件(touches changedTouches)
- Dataset是视图组件上的数据,可以传递给逻辑层,注意-会变成驼峰,大写会变成小写
自定义组件
- 一个自定义组件分为创建 注册 使用三部曲
- 创建组件 同样需要.axml .acss .js .json(component:true)四个文件
- 组件.js文件提供
- mixins(代码复用)
- data(组件内部数据)
- props(外部属性 不可修改)
- didMount(组件渲染完成)
- didUpdate(组件更新)
- didUnmount(组件销毁)
- methods(组件内部方法)
- 注册时在需要的页面.json中添加useComponents:组件路径注册
- 使用时就像普通组件一样使用
自定义组件.js
- Js的写法与页面组件一致,事件绑定也是,但是方法是写在methods里面的。
- 自定义组件props(自定义组件与外界交流的方式)不可修改
- 自定义组件在props里面声明默认值,自定义组件的axml可以直接使用,methods里面通过this.props来使用
- 自定义组件的生命周期
- didMount
- didUpdate(组件内部调用this.setData会触发 外部调用者调用this.setData也会触发)
- didUnmount
自定义组件的mixins
- Mixins实现组件代码的复用,mixin只支持data props methods 和生命周期的属性
自定义组件的其他属性
- $id(组件id)
- $page(调用组件的页面实例)
- is(组件实例本身)
Axml
- 自定义组件的axml中,自定义事件定义在.js的methods里
- Slot(自定义组件除了可以接收外部调用者的数据,通过事件告知外部调用者数据变化,还可以接收外部调用这的axml结构)
- 自定义组件slot插槽来接收外部调用者传入的axml结构
- 自定义组件slot插槽name属性实现具名插槽
- 但是传入的axml只能使用外部调用者的数据,通过给slot传入数据,产生props对象,在外部调用者添加slot-scope可以接收到这个props
兼容
支付宝老版本可能不支持新的api或者组件方法,需要做兼容处理
// apiif(api)(){}else{提示}// api参数if(my.canIUse(‘api参数’)){}else{提示}// 方法兼容组件内部Data:{ canIUse:’组件方法’}同时axml使用条件渲染复制代码
优化
小程序的执行包含webview(负责渲染)和worker(负责存储数据和执行业务逻辑)两块,数据改变,调用setData,worker序列化data,异步传递给webview进行渲染(构造虚拟dom,进行diff),渲染完成后再通知worker
- 从运行原理上就知道,worker丢给webview的数据不能过大
首屏优化
- 资源包不能过大(清理图片/cdn图片/无用代码)
- Onload加载首屏数据(小程序执行时就已经走了一遍worker->webview,webview渲染好后通知worker,执行onready,故在onload就加载初始数据)
- Webview的首屏节点别太多
setData(触发重新渲染的途径)
- 数据别太大,尽量使用指定路径设置数据
- 多封装组件,将业务丢进组件里面,多触发组件级别的内部渲染,减少页面级别的渲染(也可挂载外部调用者来触发)
- 长序列用$spliceData,这样只会渲染指定节点
key
- 在列表渲染使用key