本文章同步发布在我的博客:xueshiming.cn
Tips: 先来一些干货
wx:key 不仅仅是唯一标识
列表数据发生改变重新出发页面渲染的时候,列表中的项目可以保持自身状态 比如在input
组件里,输入了内容之后 在页面渲染之后,不希望input
内容发生改变,需要用此属性 这个属性,在页面重新渲染的时候,确保带有 key
的组件 会重新排序,而不是重新渲染,从而提高页面渲染性能的效率
另外:如不提供 wx:key
,会报一个 warning
, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
Block是一个包装元素,不是组件,渲染之后页面看不出来
wx:if 和hidden 区别
wx:if
在切换时有局部渲染的过程,从而保证条件块渲染时,可以销毁并重新渲染,有更高的切换消耗 hidden
始终渲染。可以控制视图上的显示和隐藏,有更高的初始化渲染消耗, 所以元素频繁切换的话,使用hidden
wxml支持文件引用
import
: 只能引用我们定义模板文件的模板内容块
template
模板,如果目标文件内嵌套了其他模板,是不会被引用的,避免了引用模板死循环的问题
include
: 把目标 文件内除了模板代码块外的 所有代码都引入,相当于拷贝到了
include
位置这里
Wxss和css对比
尺寸单位rpx
先了解几个概念:
设备像素
: 设备能控制的显示的最小物理单位 这个最小物理单位是屏幕上一个个点,点是固定不变的CSS像素
:外部编程的概念,css代码中使用的逻辑像素PPI/DPI
:每英寸拥有的像素数目
DPR
:手机的某一方向上设备像素和css像素之比
虽然wxss
支持rem
,但是我们知道rem
是根据html
根元素的fontSize
大小来适配的, wxss
不能直接操作html
的样式属性,所以rem
适配方案就失效了。 rpx
应运而生,规定屏幕宽度为750rpx
,从而我们可以根据屏幕宽度来自适应,rpx
和rem
实现方式是相似的,而且rpx
最终转换为rem
样式导入
-
外联样式引入:
@import ‘./ss.wxss’
-
内连样式引入:
style
一般用来写动态的样式
选择器
优先级
一般想要修改他人插件样式的时候使用!import
小程序运行机制
小程序两种启动方式:冷启动,热启动
- 热启动:假如用户已经打开了某个小程序,在一定时间内再次打开小程序的话,这个时候我们就不再需要重新启动了,这需要把我们的后台打开的小程序切换到前台来使用。
- 冷启动:用户首次打开小程序或被微信主动销毁再次打开的情况,此时小程序需要重新加载启动。
小程序什么时候会主动销毁?
- 小程序在进入后台之后,客户端会帮我们在一定时间内维持我们的一个状态,超过五分钟后,会被微信主动销毁
- 当我们在短时间内连续两次收到系统告警的时候,微信就会主动销毁,短时间间隔是5s
小程序更新机制:
小程序在冷启动的时候遇到版本更新,小程序会异步加载,帮我们下载最新版本的代码包,并同时使用微信本地版本的代码包启动,也就是说最新的代码包,将在小程序下次启动才去加载。如果偏要使用最新版本的代码包,我们可以使用api来处理
wx.getUpdateManager
const updateManager = wx.getUpdateManager()
updateManager.onCheckForUpdate(function (res) {
// 请求完新版本信息的回调
console.log(res.hasUpdate)
})
updateManager.onUpdateReady(function () {
wx.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
success(res) {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate()
}
}
})
})
updateManager.onUpdateFailed(function () {
// 新版本下载失败
})
复制代码
小程序加载机制:
小程序的启动流程图里面:
左侧的部分是在启动的时候,微信客户端里面的视图层和逻辑层一些交互逻辑以及数据缓存的存取操作,在小程序启动的时候,会向cdn
请求最新代码包,第一次启动必须等到代码包下载完毕,注入到
webView
容器内执行之后,才能看到小程序页面,所以在网络不好的情况下,我们会感觉到页面打开比较慢,客户端会帮我们把代码包缓存到本地,当我们下一次启动的时候,我们会从
cdn
请求是否有最新版本的代码包。
小程序应用和页面的生命周期:
小程序应用生命周期:onLaunch,onShow,onHide,onError
首次进入小程序,从 cdn
或者小程序本地拿到代码包注入到运行环境, 微信客户端会给我们逻辑层app.js
的app
实例来派发onLaunch
事件, 在逻辑层,app.js
的 app
构造器的参数里面的onLaunch
方法就会被调用。 当用户使用home
件或者点击右上角小程序关闭按钮,来关闭小程序时,小程序是没有被直接销毁的,这时app
构造器的参数里面的onHiede
方法就会被调用,当我们再次打开小程序时,微信唤起小程序,onShow
方法就会被调用, 当小程序脚本发现错误时,或api
调用失败时,会调用onError
。
小程序页面的生命周期:onLoad,onShow,onReady,onHide,onUnload,
页面未被销毁之前,onLoad
只会调用一次, 页面显示之后,会调用page实例里面的onShow
当页面初次渲染之后,onReady
就会被调用,页面未被销毁之前,只会调用一次 onReady
触发之后,逻辑层和视图层进行交互, 当我们在当前页面打开新的页面之后,当前页面会触发onHide
, 如果关闭当前页,会触发onUnload
负责页面视图的view
线程和处理数据的服务以及服务的服务线程,AppService
, 协同完成生命周期周期调用
小程序事件模型
1. 事件捕获阶段
绑定的事件从最外层节点向下传递到目标节点元素,依次检查,所经过的节点是否绑定了同一事件类型的监听回调函数,如果有则执行对应的事件回调函数
2. 事件处理阶段
事件在到达目标节点之后,会触发目标节点所绑定的监听回调函数
3. 事件冒泡阶段
事件从目标节点,向上冒泡到最外层节点,依次检查经过的节点是否绑定了,同样事件类型的监听回调函数,如果有,会执行这个回调函数
target
属性: 触发事件的当前组件 currentTarget
属性: 触发事件的根源组件
eg:
如果有外层view
还有个里层view
嵌套,都通过bind
绑定了点击事件,target
为外层view
组件的事件对象,currentTarget
为底层view
组件的事件对象
type
触发事件的触发类型timestamp
触发事件的时间戳target
触发事件的根源组件,包括触发事件根源组件的id自定义属性的集合currenTarget
事件绑定额当前组件 ,包括当前组件的id
,类型,data
自定义属性的集合touches
是一个数组,每一个元素都是一个touc
h对象 ,标识当前停留在屏幕上的触摸点和信息changedTouches
是一个数据,标识有变化的 触摸点,即当前触摸点从有到无或从无到有的变化detail
标识各个事件带有的数据,点击事件: ‘触摸点距离文档左上角的距离’ 媒体事件,触发事件的时候播放状态,以及时间戳
小程序运行环境:
在不同环境下的
javascript
脚本运行环境是不同的,微信小程序运行在三端:iOS(iPhone/iPad)
、Android
和 用于调试的开发者工具。
三端的脚本执行环境以及用于渲染非原生组件的环境是各不相同的:
-
在
iOS
上,小程序逻辑层的javascript
代码运行在JavaScriptCore
中,视图层是由WKWebView
来渲染的,环境有iOS8
、iOS9
、iOS10
; -
在
Android
上,- 旧版本,小程序逻辑层的
javascript
代码运行中X5 JSCore
中,视图层是由X5
基于Mobile
Chrome 57
内核来渲染的 - 新版本,小程序逻辑层的
javascript
代码运行在V8
中,视图层是由自研XWeb
引擎基于Mobile Chrome 6
7 内核来渲染的;
- 旧版本,小程序逻辑层的
-
在 开发工具上,小程序逻辑层的
javascript
代码是运行在NW.js
中,视图层是由Chromium 60 Webview
来渲染的。
结语:我们在开发小程序的同时,也别忘记去理解一些原理性和细节性问题,因为这是提升的关键。to be an engineer,not a coder.