1、你是怎么封装小程序数据请求的?
- 我们会在现在小程序根目录下,创建一个config.js作为一个独立的模块,用以放置API前缀及其它需要全局配置的相关配置,然后通过export 导出,供其它模块调用;
- 创建utils目录,然后再创建http.js文件,在这个文件里我们会用promise把wx.request封装成一个HTTP的父类;
- 我们会在项目的models目录下也就是数据层,再创建一个子类然后继承父类HTTP,在这个子类里面会编写具体的API请求;
- 最后在视图层的JS中,完成数据的获取及绑定,渲染到视图。
2、有哪些传值的方法?
- navigator组件或wx.navigator;
- 本地存储;
- app.js中的全局对象;
- 自定义属性data-xxx;
3、在项目中你如何优化小程序的速度?
- 控制上传包的大小
- 勾选开发者工具中“上传代码时,压缩代码”选项
- 及时清理无用的代码和资源文件(包括无用的日志代码)
- 减少资源包中的图片等资源的数量和大小(理论上除了小icon,其他图片资源从网络下载),图片资源压缩率有限
- 采用分包加载机制
- 根据业务场景,将用户访问率高的页面放在主包里,将访问率低的页面放入子包里,按需加载;
- 将小程序中不经常使用的页面放到多个分包内,主包只保留最常用的核心页面;
- 使用分包时需要注意代码和资源文件目录的划分。启动时需要访问的页面及其依赖的资源文件应放在主包中。
- 采用分包预加载技术
- 在上一条的基础上,当用户点击到子包的目录时,还是有一个代码包下载的过程,这会感觉到明显的卡顿,所以子包也不建议拆的太大,当然我们可以采用子包预加载技术,并不需要等到用户点击到子包页面后在下载子包,而是可以根据后期数据,做子包预加载,将用户在当先页可能点击的子包页面先加载,当用户点击后直接跳转;
- 这种基于配置的子包预加载技术,是可以根据用户网络类型来判断的,当用户处于网络条件好时才预加载,是灵活可控的。
- 首屏加载的优化建议
- 利用缓存storage API, 对变动频率比较低的异步数据进行缓存,二次启动时,先利用缓存数据进行初始化渲染,然后后台进行异步数据的更新,这不仅优化了性能,在无网环境下,用户也能很顺畅的使用到关键服务;
- 避免白屏,可以在前置页面将一些有用的字段带到当前页,进行首次渲染(列表页的某些数据–> 详情页),没有数据的模块可以进行骨架屏的占位,使用户不会等待的很焦虑,甚至走了;
- 及时反馈,及时的对需要用户等待的交互操作进行反馈,避免用户以为小程序卡了,无响应。
- 避免使用不当setData
- 不要过于频繁调用setData,应考虑将多次setData合并成一次setData调用;
- 数据通信的性能与数据量正相关,因而如果有一些数据字段不在界面中展示且数据结构比较复杂或包含长字符串,则不应使用setData来设置这些数据;
- 与界面渲染无关的数据最好不要设置在data中,可以考虑设置在page对象的其他字段下
- 用户事件使用不当
- 视图层将事件反馈给逻辑层时,同样需要一个通信过程,通信的方向是从视图层到逻辑层。因为这个通信过程是异步的,会产生一定的延迟,延迟时间同样与传输的数据量正相关,数据量小于64KB时在30ms内。降低延迟时间的方法主要有两个。
- 去掉不必要的事件绑定(WXML中的bind和catch),从而减少通信的数据量和次数;
- 事件绑定时需要传输target和currentTarget的dataset,因而不要在节点的data前缀属性中放置过大的数据。
- 视图层渲染原理
- 首次渲染(优化视图节点),初始渲染发生在页面刚刚创建时。初始渲染时,将初始数据套用在对应的WXML片段上生成节点树。节点树也就是在开发者工具WXML面板中看到的页面树结构,它包含页面内所有组件节点的名称、属性值和事件回调函数等信息。最后根据节点树包含的各个节点,在界面上依次创建出各个组件。在这整个流程中,时间开销大体上与节点树中节点的总量成正比例关系。因而减少WXML中节点的数量可以有效降低初始渲染和重渲染的时间开销,提升渲染性能。
- 重渲染(减少setData数据量),初始渲染完毕后,视图层可以多次应用setData的数据。每次应用setData数据时,都会执行重渲染来更新界面。初始渲染中得到的data和当前节点树会保留下来用于重渲染。每次重渲染时,将data和setData数据套用在WXML片段上,得到一个新节点树。然后将新节点树与当前节点树进行比较,这样可以得到哪些节点的哪些属性需要更新、哪些节点需要添加或移除。最后,将setData数据合并到data中,并用新节点树替换旧节点树,用于下一次重渲染。在进行当前节点树与新节点树的比较时,会着重比较setData数据影响到的节点属性。因而,去掉不必要设置的数据、减少setData的数据量也有助于提升这一个步骤的性能。
- 使用自定义组件
- 自定义组件的更新只在组件内部进行,不受页面其他不能分内容的影响;比如一些运营活动的定时模块可以单独抽出来,做成一个定时组件,定时组件的更新并不会影响页面上其他元素的更新;各个组件也将具有各自独立的逻辑空间。每个组件都分别拥有自己的独立的数据、setData调用。
4、小程序与原生APP对比,分别说出他们优劣?
VS | 小程序 | 原生APP |
---|---|---|
开发成本 | 开发成本低 | 开发成本高 |
开发周期 | 一次开发多终端适配(跨平台) | 多次开发 |
功能实现 | 限于微信平台提供的API,较为单一 | 业务复杂、灵活 |
内存占用 | 无需安装,用完即走 | 需安装于手机,太多APP可能会导致空间不足 |
消息推送 | 仅能回复模板消息。不允许主动给用户发送广告,良好的产品体验 | 频繁的广告推送,造成骚扰 |
应用场景 | 简单的用完即走,性能要求不高的,低频的应用 | 可以承担性功能较高及高频的应用 |
5、简述微信小程序原理
1. 小程序是个啥?
本质其实就是(混合)的app 介于web app与native 原生app之间,具备丰富的调用手机各种功能的接口,同时又具备灵活性,跨平台
2. 小程序的开发流程:
申请小程序帐号(获得appid)、安装小程序开发者调试工具、配置项目等等
3. 小程序和传统web的区别
web网页开发渲染线程和脚本是互斥的,而小程序对于两者是分开的,分别运行在不同的进程中,是基于双线程的
小程序逻辑层和渲染层是分开的所以没有DOM、BOM,相关API也不能使用(所以好多第三方和dom有关的库也不能使用)
每个页面都是不同的webview渲染,减轻了单个webview的压力
4. 运行环境差异
运行环境 | 逻辑层 | 渲染层 |
---|---|---|
iOS | JavaScriptCore | WKWebView |
Android | X5 JSCore | X5浏览器 |
小程序开发工具 | NWJS | Chrome WebView |
5. 小程序的代码组成
- 与 web 开发(HTML,CSS,JS)类同,小程序由配置代码 JSON 文件、模板代码 WXML 文件、样式代码 WXSS 文件以及逻辑代码 JavaScript 文件组成。
- JSON 文件:在小程序代码中扮演静态配置的作用,在小程序运行之前就决定了小程序一些表现(设置 navigationBarTitleText 等),需要注意的是小程序是无法在运行过程中去动态更新 JSON 配置文件从而发生对应的变化的。
- WXML 全称是 WeiXin Markup Language,是小程序框架设计的一套标签语言,结合小程序的基础组件、事件系统,可以构建出页面的结构。
- 数据绑定:用户界面呈现会因为当前时刻数据不同而有所不同,或者是因为用户的操作发生动态改变,这就要求程序的运行过程中,要有动态的去改变渲染界面的能力。在 Web 开发中,开发者使用 JavaScript 通过 Dom 接口来完成界面的实时更新。在小程序中,使用 WXML 语言所提供的数据绑定功能,来完成此项功能。
-
WXSS(WeiXin Style Sheets)是一套用于小程序的样式语言,用于描述WXML的组件样式,也就是视觉上的效果。
在小程序开发中,开发者不需要像 Web 开发那样去优化样式文件的请求数量,只需要考虑代码的组织即可。样式文件最终会被编译优化。
在WXSS中,引入了rpx(responsive pixel)尺寸单位。引用新尺寸单位的目的是,适配不同宽度的屏幕,开发起来更简单。小程序编译后,rpx会做一次px换算。换算是以375个物理像素为基准,也就是在一个宽度为375物理像素的屏幕下,1rpx = 1px。
6. 渲染原理(重要)
小程序的渲染层和逻辑层分别由两个进程管理,通信会由微信客户端做中转。
1、通信模型
- 微信小程序的框架包含两部分渲染层(View)和逻辑层(App service)。
View层用来渲染页面结构,APPService层用来处理,数据请求,接口调用,它们在两个线程里运行。
VIew层使用WebView渲染,逻辑层使用JSCore运行。 - 视图层和逻辑层是通过微信客户端(WeixinJsBridage),来通信的。逻辑层把数据变化通知到视图层,触发视图层页面更新,视图层把触发的事件通知到逻辑层进行业务处理。
小程序的运行环境分成渲染层和逻辑层, WXML 模板和 WXSS 样式工作在渲染层,JS 脚本工作在逻辑层。渲染层和逻辑层是分离的。 -
小程序的渲染层和逻辑层分别由2个线程管理:渲染层的界面使用了WebView 进行渲染;逻辑层采用JsCore线程运行JS脚本。一个小程序存在多个界面,所以渲染层存在多个WebView线程,这两个线程的通信会经由微信客户端(下文中也会采用Native来代指微信客户端)做中转,逻辑层发送网络请求也经由Native转发。
2、数据驱动
- 数据驱动使得数据状态和视图绑定在一起,wxml文件对应着一个js对象,可以假使这是一个dom树,当数据变化时,直接修改dom树对应的js对象,wxml对比js对象前后的差别然后进行部分渲染。这个原理听起来很熟悉嘛?是的,和vue、react的虚拟DOM大同小异,都是为了避免重复渲染“dom”做的优化。
渲染层和数据相关。
逻辑层负责产生、处理数据。
逻辑层通过 Page 实例的 setData 方法传递数据到渲染层。
3、全局数据
因为渲染层和逻辑层的分离,每打开一个页面都会各自又一个 WebView进程进行渲染,在逻辑层的JS脚本运行上下文依旧在一个进程中没有变。所以App里的globalData是可以全局获取到的
7. 数据驱动
数据驱动使得数据状态和视图绑定在一起,wxml文件对应着一个js对象,可以假使这是一个dom树,当数据变化时,直接修改dom树对应的js对象,wxml对比js对象前后的差别然后进行部分渲染。这个原理听起来很熟悉嘛?是的,和vue、react的虚拟DOM大同小异,都是为了避免重复渲染“dom”做的优化。
8. 全局数据
因为渲染层和逻辑层的分离,每打开一个页面都会各自又一个 WebView进程进行渲染,在逻辑层的JS脚本运行上下文依旧在一个进程中没有变。所以App里的globalData是可以全局获取到的。
6、分析小程序优劣
7、小程序与h5的区别
简单来说,小程序是一种应用,运行的环境是微信(App);H5是一种技术,依附的外壳是是浏览器。
- 运行环境的不同
- H5的运行环境是浏览器,包括webview,而微信小程序的运行环境并非完整的浏览器,因为小程序的开发过程中只用到一部分H5技术。
- 小程序的运行环境是微信开发团队基于浏览器内核完全重构的一个内置解析器,针对性做了优化,配合自己定义的开发语言标准,提升了小程序的性能。
2.系统权限
- 这里的系统权限,可以理解为隐私级别比较高的,如通讯录,或能调用硬件的,比如蓝牙功能等。从这个角度看,H5 本身可以说几乎是没有什么系统权限的。虽然也有摄像头之类的接口,但是重度依赖浏览器能力,兼容性有限。
- 而小程序,由于依赖微信客户端本身,所以微信小程序团队将客户端的很多能力开放给了小程序环境,当然,前提是你给微信也授权了相关的能力,比如允许访问麦克风,允许访问相册等。
所以,如果你的产品重度依赖这些能力,那小程序一定是不二之选,因为 H5 很难做到这些,对于很多小程序提供的能力,H5 是根本没有可能实现的。
- 开发成本
- H5 的开发,涉及开发工具(vscode、Atom等)、前端框架(Angular、react等)、模块管理工具(Webpack 、Browserify 等)、任务管理工具(Grunt、Gulp等),还有UI库选择、接口调用工具(ajax、Fetch Api等)、浏览器兼容性等等。尽管这些工具可定制化非常高,大部分开发者也有自己的配置模板,但对于项目中各种外部库的版本迭代、版本升级,这些成本加在一起那就是个不小数目了。
- 而开发一个微信小程序,由于微信团队提供了开发者工具,并且规范了开发标准,则简单得多。前端常见的HTML、CSS变成了微信自定义的WXML、WXSS,WXML,官方文档中都有明确的使用介绍,开发者按照说明专注写程序就可以了。需要调用后端接口时,调用发起请求API;需要上传下载时,调用上传下载API;需要数据缓存时,调用本地存储API;引入地图、使用罗盘、调用支付、调用扫码等等功能都可以直接使用;UI库方面,框架带有自家weui库加成。并且在使用这些API时,不用考虑浏览器兼容性,不用担心出现BUG,显而易见微信小程序的开发成本相对低很多。
- 运行流畅度的不同
- 在运行流畅度方面,无论对于用户还是开发者,都可以直观体验出两者的差异。这也是普通大众最容易区分小程序与H5的一点。打开H5,实际上是打开一个网页,而网页需要在浏览器中渲染。所以加载这一过程,会给人明显的「卡顿」感觉,面对复杂的业务逻辑或者丰富的页面交互时尤为明显。
- 而微信小程序,它的代码直接在微信上运行,省去了通过浏览器渲染的步骤,因此,在微信中使用小程序,才会比H5流畅很多。除了首次打开需要几秒的加载时间外,小程序各个页面的切换、跳转等体验已经媲美原生App,有着同样的柔丝般顺滑的效果。
- 迭代周期
- 开发成本低,未必迭代周期就短。对于 H5 我们可以随时发布上线,不用受任何牵制。而小程序的特点,就是每次提交版本都要经过微信方面的审核,且审核时间的长短很随机,着急上线的项目就很无奈了。
至于其他速度,取决于开发人员技能熟练程度,系统复杂度,对基础能力的依赖等,就不好估算了。
- 访问入口
- 在访问入口这个点上,H5 的核心竞争力就是能在微信之外玩,不依赖微信本身。而小程序的优势,就是有 50+ 微信提供的场景入口,并且聊天界面顶部的“最近使用”和“我的小程序”这个入口,相对 H5 来说是有绝对优势的。
- 用户关闭之后,H5 页面如果想继续访问,可能会通过收藏入口,或者转发给“文件传输助手”等聊天界面保存,还可以缩小到图标稍后阅读等等。本质上还是跟 PC 时代的浏览器收藏夹差不多,需要有个地方把 H5 的链接地址保存下来,方便下次访问。如果没有保存,下次就很难找到了。
- 至于微信内的搜索,是可以同时搜索 H5 和小程序的,可以根据 H5 的名字和内容、小程序的名字和介绍来搜索。这里 H5 有个天然优势就是,只要你的链接在各大搜索引擎提交过,那么使用其他的搜索引擎也能搜出这个 H5,比如百度搜索。
- 外部限制
- 由于小程序依赖微信平台,因此微信平台要对内容安全等事项负责,比如你想搞个有 UGC 的产品,用 H5 可能还可以趁着监管宽松无证裸奔一阵,或者说做大了再补证。
- 而小程序,就很可能完全不能过审,根本上不了线。比如试听类,社交类,都有对应的资质,而这个资质还可能很难获得。
- 类似的,H5 页面可以不用搞 HTTPS,有个网站就能玩,甚至用工具做个小活动也都可以玩。但是小程序,从后端开始就有限制,要求域名备案+HTTPS,一定程度上也是一点成本。
- 此外,小程序对文件大小也有限制,虽然现在已经支持分包加载,但是在文件大小方面,H5 本身是没有什么限制的。只是实际开发的时候,要照顾用户的体验,不能让页面打开太慢。
8、怎么解决小程序的异步问题
- 场景一(常见):
- 项目需要获取code值,在app实例中也就是app.js中定义一个getCode的方法,success之后,在page中的index.js中的onload生命周期中拿到code,通过wx.request传递给后台来换取openid。
想的很完美,但是实现时发现,在wx.login还未执行完就执行了page的onLoad;
这种异步情况可以使用promise来解决,示例代码如下:
//app.js
App({
// 获取code,然后传递给index.js中的onload生命周期
getCode (data) {
let _this= this
return new Promise((resolve => {
wx.login({
success: function (res) {
//模拟异步请求 - 3秒后返回数据 - resolve出去
setTimeout(() => {
resolve(res)
}, 3000)
}
})
}))
}
})
//index.js
//获取应用实例
const app = getApp()
Page({
data: {
},
onLoad: function () {
// 通过app实例获取到异步返回的数据 - code
app.getCode().then(res => {
console.log(res.code) // 成功返回;如果不用promise,那code的返回值就是空
})
}
})
9、小程序的双向数据绑定和Vue有何不同
小程序直接this.data的属性是不可以同步到视图的,必须调用:
this.setData({})
10、小程序的wxml和html有什么区别?
- HTML是用于创建网页的语言。通过使用HTML标记标签创建html文档来创建网页。
11、小程序的wxss和css有什么区别?
- WXSS(WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。
WXSS 用来决定 WXML 的组件应该怎么显示。
为了适应广大的前端开发者,WXSS 具有 CSS 大部分特性。同时为了更适合开发微信小程序,WXSS 对 CSS 进行了扩充以及修改。
与 CSS 相比,WXSS 扩展的特性有:
尺寸单位
12、详述小程序的生命周期
很多同学容易将小程序生命周期和页面的生命周期混淆为一起,这两个其实应该是不同却又相互关联的生命周期
- 小程序启动后,首先完成小程序的初始化(onLaunch)和显示(onShow),然后是页面的加载(onLoad)、显示(onShow)和渲染(onReady)。如图“小程序的生命周期”。
- 小程序进入后台时,先触发页面的生命周期函数onHide,再触发小程序的生命周期函数onHide;小程序启动显示或从后台进入前台时,先触发小程序的生命周期函数Onshow,再触发页面的生命周期函数onShow。
- 这里解释两个概念:
后台: 当用户点击左上角关闭(或者右上角退出),或者按了home键离开微信,小程序并没有直接销毁,而是进入了后台。
前台: 当再次进入微信或者再次打开小程序,又会从后台进入前台。
只有当小程序进入后台一定时间(目前是5分钟),或者系统资源占用过高,才会被真正的销毁。
- 初始化:视图线程开始初始化,初始化完成发送通知到逻辑线程,视图线程开始等待数据,(逻辑线程初始化完成后等待视图线程的通知,)逻辑线程返回页面初始数据,逻辑线程进入等待激活状态。
- 首次渲染:视图线程拿到初始化渲染数据后,开始首次渲染,渲染完成后(视图层进入持续渲染状态)发送 【初始化完成通知】给逻辑线程,触发生命周期函数onReady,逻辑线程进入激活态。
- 持续渲染状态: 用户交互触发事件,逻辑线程处理,通过this.setData更新数据到渲染线程,数据更新,渲染线程局部更新页面。
- 前台->后台: 用户关闭小程序或home键退出微信,逻辑线程触发生命周期函数onHide进入后台态。
- 后台->前台:用户再次打开微信或小程序,逻辑线程触发生命周期函数onShow进入激活态。
- 销毁:页面或小程序被系统回收或销毁时,逻辑线程触发生命周期函数onUnload,结束。
13、详述小程序组件中的生命周期
- 组件的生命周期,指的是组件自身的一些函数,这些函数在特殊的时间点或遇到一些特殊的框架事件时被自动触发。
- 其中,最重要的生命周期是
created
attached
detached
,包含一个组件实例生命流程的最主要时间点。
- 组件实例刚刚被创建好时,
created
生命周期被触发。此时,组件数据this.data
就是在Component
构造器中定义的数据data
。 此时还不能调用setData
。 通常情况下,这个生命周期只应该用于给组件this
添加一些自定义属性字段。 - 在组件完全初始化完毕、进入页面节点树后,
attached
生命周期被触发。此时,this.data
已被初始化为组件的当前值。这个生命周期很有用,绝大多数初始化工作可以在这个时机进行。 - 在组件离开页面节点树后,
detached
生命周期被触发。退出一个页面时,如果组件还在页面节点树中,则detached
会被触发。
定义生命周期方法
生命周期方法可以直接定义在 Component
构造器的第一级参数中。
自小程序基础库版本 2.2.3 起,组件的的生命周期也可以在 lifetimes
字段内进行声明(这是推荐的方式,其优先级最高)。
示例代码如下:
Component({
lifetimes: {
attached() {
// 在组件实例进入页面节点树时执行
},
detached() {
// 在组件实例被从页面节点树移除时执行
},
},
// 以下是旧式的定义方式,可以保持对 <2.2.3 版本基础库的兼容
attached() {
// 在组件实例进入页面节点树时执行
},
detached() {
// 在组件实例被从页面节点树移除时执行
},
// ...
})
在 behaviors 中也可以编写生命周期方法,同时不会与其他 behaviors 中的同名生命周期相互覆盖。但要注意,如果一个组件多次直接或间接引用同一个 behavior ,这个 behavior 中的生命周期函数在一个执行时机内只会执行一次。
可用的全部生命周期如下表所示:
生命周期 | 参数 | 描述 |
---|---|---|
created | 无 | 在组件实例刚刚被创建时执行 |
attached | 无 | 在组件实例进入页面节点树时执行 |
ready | 无 | 在组件在视图层布局完成后执行 |
moved | 无 | 在组件实例被移动到节点树另一个位置时执行 |
detached | 无 | 在组件实例被从页面节点树移除时执行 |
error | Object Error | 每当组件方法抛出错误时执行 |
组件所在页面的生命周期
还有一些特殊的生命周期,它们并非与组件有很强的关联,但有时组件需要获知,以便组件内部处理。这样的生命周期称为“组件所在页面的生命周期”,在 pageLifetimes 定义段中定义。其中可用的生命周期包括:
生命周期 | 参数 | 描述 |
---|---|---|
show | 无 | 组件所在的页面被展示时执行 |
hide | 无 | 组件所在的页面被隐藏时执行 |
resize | 无 | 组件所在的页面尺寸变化时执行 |
示例代码如下:
Component({
pageLifetimes: {
show() {
// 页面被展示
},
hide() {
// 页面被隐藏
},
resize(size) {
// 页面尺寸变化
}
}
})
14、详述小程序的组件通信
- 父传子
在子组件的组件标签上通过自定义属性的形式绑定数据或字符串
在子组件中通过properties对象进行属性的接收即可。
- 子传父
在子组件中的methods对象中定义方法,在方法中通过this.triggerEvent({})方法,完成事件触发
在子组件标签上绑定(例:bind:在this.triggerEvent定义的事件名称="回调函数" ),在this.triggerEvent定义的事情名称,最后在回调函数中完成逻辑处理。
- 兄弟
子传父
父作为中转
父传子
15、小程序中的wxs是什么?如何使用?在项目中哪里使用过?
WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。
- WXS是为了结合WXML诞生、使用的(既可以引入也可以直接写在WXML里),因为JavaScript不能在WXML中调用或直接在WXML里面写JavaScript。WXS和JavaScript是两种不相关的语言,因此在WXS中不能使用JavaScript的语法,更不能使用ES6的语法。WXS仅仅是语法形式和JavaScript很像,但是并不等同于JavaScript,WXS是有自己独立的运行环境的,再强调一遍,从根本上来说这两种就是不同的语言,只是在语法上借鉴了JavaScript。具体用法可参考 官方文档
- 我们在实际开发中经常用到的一个地方就是编写过滤器,但是大家不要错误的认为WXS就是为了在小程序编写过滤器而生的,大家一定要深刻理解WXS是小程序自己的一套脚本语言,主要是为了增强WXML的编程能力的.
16、详述在开发小程序中遇到的问题及解决方案
17、bind和catch绑定事件有什么区别?
- 事件分为冒泡事件和非冒泡事件:
冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。 - bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡。
18、详述小程序授权流程
- 微信授权机制,现版本和早起的版本有所差别,但是只是授权流程思路上的小小差异,整体并无太大变化。
早期版本是直接通过wx.getUserInfo() API来弹出微信授权窗口“询问是否授权”,主动弹出授权窗口太过灵活对于用户而言并非良好的体验,因此现版本修改为了必须通过button组件,让用户去主动触发才能弹出授权窗口,直接调用wx.getUserInfo()已不再出现授权弹窗
wx.getSetting(Object object) 判断是否已授权 - 详情参考官网
wx.getUserInfo(Object object) 获取授权后的用户信息 - 详情参考官网
button 通过button组件询问用户是否授权 - 详情参考官网
19、如何检测用户的微信版本是否支持某项功能或API
20、如何分包加载优势在哪
什么是分包加载?
某些情况下,开发者需要将小程序划分成不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。
在构建小程序分包项目时,构建会输出一个或多个分包。每个使用分包小程序必定含有一个主包。所谓的主包,即放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本;而分包则是根据开发者的配置进行划分。
在小程序启动时,默认会下载主包并启动主包内页面,当用户用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示。目前小程序分包大小有以下限制:
整个小程序所有分包大小不超过 8M
单个分包/主包大小不能超过 2M分包加载的好处
对小程序进行分包,可以优化小程序首次启动的下载时间,以及在多团队共同开发时可以更好的解耦协作。分包配置
配置方法
假设支持分包的小程序目录结构如下:
├── app.js
├── app.json
├── app.wxss
├── packageA
│ └── pages
│ ├── cat
│ └── dog
├── packageB
│ └── pages
│ ├── apple
│ └── banana
├── pages
│ ├── index
│ └── logs
└── utils
开发者通过在 app.json subpackages 字段声明项目分包结构:
{
"pages": ["pages/index", "pages/logs"],
"subpackages": [
{
"root": "packageA",
"pages": ["pages/cat", "pages/dog"]
},
{
"root": "packageB",
"name": "pack2",
"pages": ["pages/apple", "pages/banana"]
}
]
}
subpackages 中,每个分包的配置有以下几项:
字段 | 类型 | 说明 |
---|---|---|
root | String | 分包根目录 |
name | String | 分包别名,分包预下载时可以使用 |
pages | StringArray | 分包页面路径,相对与分包根目录 |
independent | Boolean | 分包是否是独立分包 |
- 打包原则
声明 subpackages 后,将按 subpackages 配置路径进行打包,subpackages 配置路径外的目录将被打包到 app(主包) 中
app(主包)也可以有自己的 pages(即最外层的 pages 字段)
subpackage 的根目录不能是另外一个 subpackage 内的子目录
tabBar 页面必须在 app(主包)内 - 引用原则
packageA 无法 require packageB JS 文件,但可以 require app、自己 package 内的 JS 文件
packageA 无法 import packageB 的 template,但可以 require app、自己 package 内的 template
packageA 无法使用 packageB 的资源,但可以使用 app、自己 package 内的资源 - 低版本兼容
由微信后台编译来处理旧版本客户端的兼容,后台会编译两份代码包,一份是分包后代码,另外一份是整包的兼容代码。 新客户端用分包,老客户端还是用的整包,完整包会把各个 subpackage 里面的路径放到 pages 中。