移动端(微信小程序&uniapp)(套题)
| 选择题 | 填空题 | 问答题 | 编程题 | 试题难度 | 
|---|---|---|---|---|
| 0 | 0 | 27 | 1 | 一般 | 
问答题
- 1、 简述下 wx.navigateTo(), wx.redirectTo(), wx.switchTab(), wx.navigateBack(), wx.reLaunch()的区别
- wx.navigateTo():保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar页面
- wx.redirectTo():关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar页面
- wx.switchTab():跳转到 abBar页面,并关闭其他所有非tabBar页面
- wx.navigateBack()关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages()获取当前的页面栈,决定需要返回几层
- wx.reLaunch():关闭所有页面,打开到应用内的某个页面
 
- wx.navigateTo():保留当前页面,跳转到应用内的某个页面。但是不能跳到 
- 2、bindtap和catchtap的区别是什么
- 相同点:首先他们都是作为点击事件函数,就是点击时触发。在这个作用上他们是一样的,可以不做区分 - 不同点:他们的不同点主要是bindtap是不会阻止冒泡事件的,catchtap是阻值冒泡的 
- 3、如何实现下拉刷新
- 首先在全局 config中的window配置enablePullDownRefresh
- 在 Page中定义onPullDownRefresh钩子函数,到达下拉刷新条件后,该钩子函数执行,发起请求方法
- 请求返回后,调用 wx.stopPullDownRefresh停止下拉刷新
 
- 首先在全局 
- 4、小程序关联微信公众号如何确定用户的唯一性
- 如果开发者拥有多个移动应用、网站应用、和公众帐号(包括小程序),可通过 - unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号(包括小程序),用户的- unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,- unionid是相同的
- 6、哪些方法可以用来提高微信小程序的应用速度
- 启动加载优化- 在小程序启动时,微信会在背后完成几项工作:下载小程序代码包、加载小程序代码包、初始化小程序首页。 - 初始化小程序环境是微信环境做的工作,我们只需要控制代码包大小,和通过一些相关的缓存策略控制,和资源控制,逻辑控制,分包加载控制来进行启动加载优化。 - 勾选开发者工具中, 上传时压缩代码(若采用wepy高级版本,自带压缩,请按官网文档采取点击)精简代码,去掉不必要的WXML结构和未使用的WXSS定义。减少在代码包中直接嵌入的资源文件。(比如全国地区库,微信有自带的,在没必要的时候,勿自用自己的库)及时清理无用的资源(js文件、图片、demo页面等)压缩图片,使用适当的图片格式,减少本地图片数量等如果小程序比较复杂,优化后的代码总量可能仍然比较大,此时可以采用分包加载的方式进行优化,分包加载初始化时只加载首评相关、高频访问的资源,其他的按需加载。提前做异步请求,页面最好在onLoad时异步请求数据,不要在onReady时请求启用缓存数据策略,请求时先展示缓存内容,让页面尽快展示,请求到最新数据之后再刷新避免白屏,使用骨架屏等
 - 数据通信优化- 为了提升数据更新的性能,开发者在执行setData调用时,最好遵循以下原则: - 不要过于频繁调用setData,应考虑将多次setData合并成一次setData调用;数据通信的性能与数据量正相关,因而如果有一些数据字段不在界面中展示且数据结构比较复杂或包含长字符串,则不应使用setData来设置这些数据;与界面渲染无关的数据最好不要设置在data中,可以考虑设置在page对象的其他字段下。
 - 提升数据更新性能方式的代码示例: - Page({ onShow: function() { // 不要频繁调用setData this.setData({ a: 1 }) this.setData({ b: 2 }) // 绝大多数时候可优化为 this.setData({ a: 1, b: 2 }) // 不要设置不在界面渲染时使用的数据,并将界面无关的数据放在data外 this.setData({ myData: { a: '这个字符串在WXML中用到了', b: '这个字符串未在WXML中用到,而且它很长…………………………' } }) // 可以优化为 this.setData({ 'myData.a': '这个字符串在WXML中用到了' }) this._myData = { b: '这个字符串未在WXML中用到,而且它很长…………………………' } } })- 事件通信优化- 视图层会接受用户事件,如点击事件、触摸事件等。当一个用户事件被触发且有相关的事件监听器需要被触发时,视图层会将信息反馈给逻辑层。这个反馈是异步的,会产生延迟,降低延迟的方法有两个: - 去掉不必要的事件绑定(WXML中的bind和catch),从而减少通信的数据量和次数;事件绑定时需要传输target和currentTarget的dataset,因而不要在节点的data前缀属性中放置过大的数据。
 - 渲染优化- 页面方法onPageScroll使用, 每次页面滚动都会触发,避免在里面写过于复杂的逻辑 ,特别是一些执行重渲染页面的逻辑(另外,可以看我的文章——移动端滚动研究,说明了在滚动的情况下导致的渲染性能低下的各种分析和应付方法总结)在进行视图重渲染的时候,会进行当前节点树与新节点树的比较,去掉不必要设置的数据、减少setData的数据量也有助于提升这一个步骤的性能。 
- 7、小程序页面间有哪些传递数据的方法
- 1、使用全局变量实现数据传递 - 在 - app.js文件中定义全局变量- globalData, 将需要存储的信息存放在里面- // app.js App({ // 全局变量 globalData: { userInfo: null } })- 使用的时候,直接使用 - getApp()拿到存储的信息- 2、使用 - wx.navigateTo与- wx.redirectTo的时候,可以将部分数据放在- url里面,并在新页面- onLoad的时候初始化- //pageA.js // Navigate wx.navigateTo({ url: '../pageD/pageD?name=raymond&gender=male', }) // Redirect wx.redirectTo({ url: '../pageD/pageD?name=raymond&gender=male', }) // pageB.js ... Page({ onLoad: function(option){ console.log(option.name + 'is' + option.gender) this.setData({ option: option }) } })- 需要注意的问题: - wx.navigateTo和- wx.redirectTo不允许跳转到- tab所包含的页面- onLoad只执行一次- 使用本地缓存 - Storage相关
- 8、小程序的wxss和css有哪些不一样的地方
- WXSS 和 CSS 类似,不过在 CSS 的基础上做了一些补充和修改 - 1、WXSS 仅支持部分 CSS 选择器; - 2、WXSS 提供全局样式与局部样式 - 3、尺寸单位 - rpx- rpx是响应式像素,可以根据屏幕宽度进行自适应。规定屏幕宽为- 750rpx。如在- iPhone6上,屏幕宽度为- 375px,共有- 750个物理像素,则- 750rpx = 375px = 750物理像素- 4、使用 - @import标识符来导入外联样式。- @import后跟需要导入的外联样式表的相对路径,用;表示语句结束- /** index.wxss **/ @import './base.wxss'; .container{ color: red; }
- 10、简述微信小程序原理
- 微信小程序采用 - JavaScript、- WXML、- WXSS三种技术进行开发,本质就是一个单页面应用,所有的页面渲染和事件处理,都在一个页面内进行,但又可以通过微信客户端调用原生的各种接口- 微信的架构,是数据驱动的架构模式,它的 - UI和数据是分离的,所有的页面更新,都需要通过对数据的更改来实现- 小程序分为两个部分 - webview和- appService。其中- webview主要用来展现- UI,- appService有来处理业务逻辑、数据及接口调用。它们在两个进程中运行,通过系统层- JSBridge实现通信,实现- UI的渲染、事件的处理
- 11、简单描述下微信小程序的相关文件类型
- 微信小程序项目结构主要有四个文件类型 - WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。内部主要是微信自己定义的一套组件
- WXSS(WeiXin Style Sheets)是一套样式语言,用于描述- WXML的组件样式
- js逻辑处理,网络请求
- json小程序设置,如页面注册,页面标题及- tabBar
 - 主要文件 - app.json必须要有这个文件,如果没有这个文件,项目无法运行,因为微信框架把这个作为配置文件入口,整个小程序的全局配置。包括页面注册,网络设置,以及小程序的- window背景色,配置导航条样式,配置默认标题
- app.js必须要有这个文件,没有也是会报错!但是这个文件创建一下就行 什么都不需要写以后我们可以在这个文件中监听并处理小程序的生命周期函数、声明全局变量
- app.wxss可选
 
- 13、使用webview直接加载要注意哪些事项?
- (1)必须要在小程序后台使用管理员添加业务域名; - (2)h5页面跳转至小程序的脚本必须是1.3.1以上; - (3)微信分享只可以都是小程序的主名称了,如果要自定义分享的内容,需小程序版本在1.7.1以上; - (4)h5的支付不可以是微信公众号的appid,必须是小程序的appid,而且用户的openid也必须是用户和小程序 
- 14、小程序登录流程 / 小程序的授权登录流程
- 我最近做的微信小程序项目就实现了授权微信登录,这个流程是这样的 - 通过wx.login获得code,然后调用后台的第三方登录接口,传递code到后台,后台会将code和APPID、密钥发生到微信服务器进行身份验证,验证通过了,接口就返回令牌和用户信息到前端。 
- 15、小程序支付流程 / 怎么实现微信支付功能
- 我们项目实现的过程是这样的,用户下单后会在后台生成一个订单号,然后前端会调用后端提供的微信支付接口,把订单号传递给这个接口,接口调用成功后,会返回随机签名字符串、商户订单号、时间戳、签名、签名类型,APPID,把这些返回信息作为wx.requestPayment的参数,就可以弹出微信支付界面进行支付了 
- 16、小程序调用后台接口遇到哪些问题
- 一、数据的大小有限制,超过范围会直接导致整个小程序崩溃,除非重启小程序;2、小程序不可以直接渲染文章内容页这类型的html文本内容,若需显示要借住插件,但插件渲染会导致页面加载变慢,所以最好在后台对文章内容的html进行过滤,后台直接处理批量替换p标签div标签为view标签,然后其它的标签让插件来做,减轻前端的时间。 
- 17、开发移动端时遇到过哪些兼容性问题?你怎么解决的 / 在使用uniapp开发项目时你遇到过什么兼容性问题
- 我在使用uniapp进行多端开发时,兼容性的问题还是挺多的,我个人理解兼容性问题导致的原因就是平台运行方式的差异性导致的,我的解决手段是调试代码。 - 最近一个项目要使用uniapp开发微信小程序、H5、Android端,兼容三端,就遇到过兼容性问题。登录框要要垂直居中,在小程序对登录框容器使用高度100vh,使用弹性盒子布局,设置align-items:center就可以了,但在h5端不行,进过调试发现,H5端的导航栏是模拟出来,100vh是包含了导航栏的高度,所以在H5端就不能使用100vh。最后面的做法就是让page的高度为100%,登录框的容器也为100%,page的100%高度正好是去掉了导航栏的窗体高度,这样就兼容了三端。 - 还项目要求登录框是椭圆的,我用的是easy-input组件需要样式覆盖才能实现,发现在小程序上不行,原因是easyinput是虚拟化组件节点,添加的class不会被渲染,而在H5端是可以的,只好用view包裹起来,添加class。 - 兼容性的问题还是挺多的,一般进过分析,调试找出问题的原因,就能够很快的解决。 
- 18、你认为小程序和app的区别是什么
- 我的看法是这样的,小程序一般是指微信小程序,需要运行在微信APP上,调用硬件资源需要通过微信APP,有一定的局限性。而APP就是直接运行在手机上,获取硬件资源是非常方便的,运行也会更加流畅。 - 从开发上来说,开发一套小程序可以在Android和iOS平台上运行,这样可以减少开发成本。 - 从推广方面来说,由于微信使用的人多,推广就很方便。 - 所以现在做APP的话开发成本和推广成本都是非常高的,这就是为什么小程序受欢迎的原因。 
- 19、登录那个getUserInfo还可以使用
- 微信小程序官方发布公告,在2022年11月9号开始就不能使用了,改成了getUserProfile 返回的也是统一默认的灰色头像,昵称统一返回“微信用户” 
- 20、简述一下微信小程序项目的目录组成?
- 我讲一下我们项目的主要目录,components是项目的公共组件,pages是项目的页面文件,为了分包处理,我们也会以模块命名来存储页面文件,static用来放一些图片,utils用来放一些公共js库文件。 
- 21、简述一下uniapp项目的目录组成?
- 我讲一下我们项目的主要目录 - components是项目的公共组件 - pages是项目的页面文件,为了分包处理,我们也会以模块命名来存储页面文件 - static用来放一些图片 - utils用来放一些公共js库文件。 - config 公共配置文件 - http 网络请求 - store 状态管理 - uni_modules 第三方插件 
- 22、小程序打包上线
- 打包上线我是这么做的,上线前我会通过开发者工具的性能分析工具,扫描一下代码,看看哪些地方需要做优化,根据扫描的结果来做优化。如果文件很大会做分包处理,图片较多会放到公司的图片服务器。扫描通过后,我会用公司带有https协议的接口做测试,因为上线后的小程序必须要是https的,测试通过后我就通过开发者工具上传到服务器,在进入到小程序后台来发布小程序,每次发布都会重新定义一个新的版本号。现在审核比较快2个小时左右就能有结果。 
- 23、小程序跳转方式
- 小程序有这么5中跳转方式 - reLaunch 关闭所有的页面,打开某个页面,这个不是很常用 - switchTab 跳转到tabBar页面,关闭其它不是tabBar的页面 - redirectTo 关闭当前页面,跳转到其它非tabBar页面 - navigateTo 保留当前页面,跳转到其它非tabBar页面,比较常用,小程序左上角会有一个返回的箭头 - navigateBack 关闭当前页面,返回页面栈上一个页面或是指定的页面 
- 24、小程序的生命周期
- 小程序的生命周期周期,我理解是页面的生命周期, - onLoad 放入到页面栈时触发,可以在这里获取query参数信息 - onShow 页面显示时触发,开发比较常用,需要实时更新的数据写在这个事件上 - onReady 首次渲染页面时触发,一个页面只触发一次 - onHide 小程序后台运行时或跳转到其它页面,页面还保留在页面栈时触发 - onUnload 页面从页面栈移除是触发 
- 25、小程序分包
- 因为程序的主包文件超过2M就需要做分包处理,所以在开发项目前,我们就会按照功能模块划分好目录,其实也是分包的目录,方便在subPackages做分包配置,通过root指定分包目录,pages指定分包的页面列表,不过要注意:分包的页面不能是tabBar页面。 
编程题
- 1、怎么封装微信小程序的数据请求
- Promise封装 - const baseUrl = 'https://api.it120.cc'; const http = ({ url = '', param = {}, ...other } = {}) => { wx.showLoading({ title: '请求中,请耐心等待..' }); let timeStart = Date.now(); return new Promise((resolve, reject) => { wx.request({ url: getUrl(url), data: param, header: { 'content-type': 'application/json' // 默认值 ,另一种是 "content-type": "application/x-www-form-urlencoded" }, ...other, complete: (res) => { wx.hideLoading(); console.log(`耗时${Date.now() - timeStart}`); if (res.statusCode >= 200 && res.statusCode < 300) { resolve(res.data) } else { reject(res) } } }) }) } const getUrl = (url) => { if (url.indexOf('://') == -1) { url = baseUrl + url; } return url } // get方法 const _get = (url, param = {}) => { return http({ url, param }) } const _post = (url, param = {}) => { return http({ url, param, method: 'post' }) } const _put = (url, param = {}) => { return http({ url, param, method: 'put' }) } const _delete = (url, param = {}) => { return http({ url, param, method: 'put' }) } module.exports = { baseUrl, _get, _post, _put, _delete }- 使用 - const api = require('../../utils/api.js') // 单个请求 api.get('list').then(res => { console.log(res) }).catch(e => { console.log(e) }) // 一个页面多个请求 Promise.all([ api.get('list'), api.get(`detail/${id}`) ]).then(result => { console.log(result) }).catch(e => { console.log(e) })
 
                            