文章目录
- 微信小程序和uni-app面试问题总结
-
- 微信小程序基础
-
- [1. 微信小程序的生命周期有哪些?](#1. 微信小程序的生命周期有哪些?)
- [2. 微信小程序的页面路由有几种方式?有什么区别?](#2. 微信小程序的页面路由有几种方式?有什么区别?)
- [3. 微信小程序如何实现数据绑定和事件绑定?](#3. 微信小程序如何实现数据绑定和事件绑定?)
- uni-app基础
-
- [4. uni-app的特点和优势是什么?](#4. uni-app的特点和优势是什么?)
- [5. uni-app的生命周期有哪些?](#5. uni-app的生命周期有哪些?)
- [6. uni-app如何实现条件编译?](#6. uni-app如何实现条件编译?)
- 微信小程序进阶
-
- [7. 微信小程序如何实现自定义组件?](#7. 微信小程序如何实现自定义组件?)
- [8. 微信小程序如何实现数据缓存?](#8. 微信小程序如何实现数据缓存?)
- uni-app进阶
-
- [9. uni-app如何实现跨平台适配?](#9. uni-app如何实现跨平台适配?)
- [10. uni-app如何调用原生功能?](#10. uni-app如何调用原生功能?)
- 性能优化
-
- [11. 微信小程序性能优化有哪些方法?](#11. 微信小程序性能优化有哪些方法?)
- [12. uni-app性能优化有哪些方法?](#12. uni-app性能优化有哪些方法?)
- 实战问题
-
- [13. 如何实现微信小程序的登录授权流程?](#13. 如何实现微信小程序的登录授权流程?)
- [14. uni-app如何实现多端差异化发布?](#14. uni-app如何实现多端差异化发布?)
- [15. 如何解决uni-app或微信小程序中的常见兼容性问题?](#15. 如何解决uni-app或微信小程序中的常见兼容性问题?)

微信小程序和uni-app面试问题总结
微信小程序基础
1. 微信小程序的生命周期有哪些?
答案 :
微信小程序的生命周期分为应用生命周期和页面生命周期:
应用生命周期:
onLaunch
:小程序初始化完成时触发,全局只触发一次onShow
:小程序启动或从后台进入前台显示时触发onHide
:小程序从前台进入后台时触发onError
:小程序发生脚本错误或API调用失败时触发
页面生命周期:
onLoad
:页面加载时触发,一个页面只会调用一次onShow
:页面显示/切入前台时触发onReady
:页面初次渲染完成时触发,一个页面只会调用一次onHide
:页面隐藏/切入后台时触发onUnload
:页面卸载时触发
2. 微信小程序的页面路由有几种方式?有什么区别?
答案 :
微信小程序页面路由主要有以下几种方式:
-
wx.navigateTo:
- 保留当前页面,跳转到应用内的某个页面
- 使用
wx.navigateBack
可以返回到原页面 - 页面栈最多10层
-
wx.redirectTo:
- 关闭当前页面,跳转到应用内的某个页面
- 页面栈不会增加
-
wx.reLaunch:
- 关闭所有页面,打开到应用内的某个页面
- 清空页面栈
-
wx.switchTab:
- 跳转到tabBar页面,并关闭其他所有非tabBar页面
- 页面栈只保留目标页面
-
wx.navigateBack:
- 关闭当前页面,返回上一页面或多级页面
3. 微信小程序如何实现数据绑定和事件绑定?
答案:
数据绑定 :
使用Mustache语法(双大括号)将变量从逻辑层(Page的data)绑定到视图层:
html
<view>{{message}}</view>
在JS中:
javascript
Page({
data: {
message: 'Hello World!'
}
})
事件绑定 :
使用bind
或catch
前缀绑定事件处理函数:
html
<button bindtap="handleTap">点击我</button>
在JS中:
javascript
Page({
handleTap: function() {
console.log('按钮被点击');
}
})
bind
和catch
的区别:
bind
:事件绑定不会阻止冒泡catch
:事件绑定会阻止冒泡
uni-app基础
4. uni-app的特点和优势是什么?
答案 :
uni-app的主要特点和优势包括:
- 跨平台:一套代码可编译到iOS、Android、H5、微信小程序、支付宝小程序、百度小程序、字节跳动小程序等多个平台
- 开发效率高:基于Vue.js语法,学习成本低,开发效率高
- 性能接近原生:通过weex原生渲染引擎,提供接近原生的性能体验
- 丰富的组件和API:内置大量跨平台组件和API
- 插件生态:支持丰富的插件市场,可扩展性强
- 社区支持:活跃的开发者社区和官方支持
- 与微信小程序兼容:大部分微信小程序的API和组件在uni-app中可以直接使用
5. uni-app的生命周期有哪些?
答案 :
uni-app的生命周期分为应用生命周期、页面生命周期和组件生命周期:
应用生命周期(在App.vue中定义):
onLaunch
:初始化完成时触发onShow
:启动或从后台进入前台显示onHide
:从前台进入后台onError
:报错时触发
页面生命周期:
onLoad
:页面加载onShow
:页面显示onReady
:页面初次渲染完成onHide
:页面隐藏onUnload
:页面卸载onPullDownRefresh
:下拉刷新onReachBottom
:页面上拉触底onShareAppMessage
:用户点击右上角分享
组件生命周期(与Vue组件生命周期相同):
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
beforeDestroy
destroyed
6. uni-app如何实现条件编译?
答案 :
uni-app通过特殊的注释语法实现条件编译,以满足不同平台的特殊需求:
-
文件级条件编译 :
文件命名添加平台后缀,如:
index.vue
:通用文件index.nvue
:仅App端使用index.mp.vue
:仅小程序端使用
-
代码块条件编译 :
使用
// #ifdef
和// #endif
注释:javascript// #ifdef H5 console.log('这段代码只会在H5平台编译'); // #endif // #ifdef MP-WEIXIN console.log('这段代码只会在微信小程序平台编译'); // #endif
-
样式条件编译:
css/* #ifdef H5 */ .h5-style { color: red; } /* #endif */
-
模板条件编译:
html<!-- #ifdef APP-PLUS --> <view>这段内容只会在App端显示</view> <!-- #endif -->
微信小程序进阶
7. 微信小程序如何实现自定义组件?
答案 :
微信小程序自定义组件实现步骤:
-
创建组件 :
在项目目录中创建
components
文件夹,然后创建组件目录(如my-component
),其中包含:my-component.json
:声明这是一个组件
json{ "component": true }
my-component.wxml
:组件模板my-component.wxss
:组件样式(可选)my-component.js
:组件逻辑
-
使用组件 :
在页面的json文件中注册组件:
json{ "usingComponents": { "my-component": "/components/my-component/my-component" } }
然后在wxml中使用:
html<my-component></my-component>
-
组件通信:
- 父传子:通过properties
- 子传父:通过triggerEvent触发自定义事件
- 获取组件实例 :通过
this.selectComponent
获取子组件实例
8. 微信小程序如何实现数据缓存?
答案 :
微信小程序提供了两种数据缓存方式:
-
同步缓存:
javascripttry { wx.setStorageSync('key', 'value') // 同步存储 const value = wx.getStorageSync('key') // 同步获取 wx.removeStorageSync('key') // 同步移除 wx.clearStorageSync() // 同步清空 } catch (e) { console.error(e) }
-
异步缓存:
javascriptwx.setStorage({ key: 'key', data: 'value', success: function() { console.log('存储成功') } }) wx.getStorage({ key: 'key', success: function(res) { console.log(res.data) } }) wx.removeStorage({ key: 'key', success: function() { console.log('删除成功') } }) wx.clearStorage() // 清空所有缓存
缓存限制:
- 单个key最大1MB
- 所有数据存储上限为10MB
- 用户主动删除或长时间未使用可能被系统清理
uni-app进阶
9. uni-app如何实现跨平台适配?
答案 :
uni-app实现跨平台适配的主要方式:
-
条件编译:根据不同平台编写不同的代码(如前所述)
-
Flex布局:使用Flex布局适配不同屏幕尺寸
-
rpx单位:使用响应式像素单位,1rpx=屏幕宽度/750
-
uni-ui组件库:官方提供的跨平台UI组件库
-
API兼容处理 :
javascript// 判断平台 #ifdef H5 // H5平台代码 #endif #ifdef APP-PLUS // App平台代码 #endif
-
manifest.json配置:针对不同平台进行配置
-
页面样式适配:使用媒体查询或动态class适配不同平台
10. uni-app如何调用原生功能?
答案 :
uni-app调用原生功能的方式:
-
使用uni API :
uni-app提供了大量跨平台API,如:
javascript// 调用相机 uni.chooseImage({ success: (res) => { console.log(res.tempFilePaths) } }) // 获取地理位置 uni.getLocation({ type: 'wgs84', success: (res) => { console.log(res.latitude, res.longitude) } })
-
Native.js (仅App端):
直接调用原生API:
javascript// 获取Android设备信息 const device = plus.android.importClass('android.os.Build') console.log(device.MODEL)
-
原生插件开发:
- 对于复杂原生功能,可以开发原生插件
- 使用Android Studio或Xcode开发原生模块
- 通过uni-app的插件机制集成
-
使用5+ API(plus对象):
javascript// 获取当前应用信息 const app = plus.runtime.getProperty('appid')
性能优化
11. 微信小程序性能优化有哪些方法?
答案 :
微信小程序性能优化方法:
-
减少setData调用:
- 避免频繁调用setData
- 合并多次setData调用
- 仅setData变化的数据
-
控制WXML节点数量:
- 单个页面节点数建议少于1000个
- 复杂列表使用
wx:for
的wx:key
提高复用性 - 长列表使用
recycle-view
组件
-
图片优化:
- 使用合适的图片格式(推荐WebP)
- 按需加载图片
- 使用CDN和图片压缩
-
合理使用自定义组件:
- 将复杂页面拆分为组件
- 使用纯数据字段优化组件性能
-
预加载数据:
- 在onLoad中预加载下一页数据
- 使用
wx.preloadPage
预加载页面
-
分包加载:
- 将不常用的功能放到分包中
- 主包大小控制在2MB以内
-
使用Worker处理复杂计算:
- 将耗时操作放到Worker线程
12. uni-app性能优化有哪些方法?
答案 :
uni-app性能优化方法:
-
通用优化:
- 减少不必要的数据响应(Object.freeze冻结不需要响应式的数据)
- 合理使用v-if和v-show
- 列表渲染使用:key
-
App平台优化:
- 使用nvue代替vue(对性能要求高的页面)
- 使用weex原生渲染
- 使用subNVue原生子窗体
-
小程序平台优化:
- 使用小程序的分包加载
- 优化setData调用
-
H5平台优化:
- 使用路由懒加载
- 使用CDN加速静态资源
- 开启gzip压缩
-
图片优化:
- 使用合适的图片格式
- 实现懒加载
- 使用雪碧图减少请求
-
代码优化:
- 合理使用条件编译减少冗余代码
- 按需引入组件和API
- 使用tree-shaking删除无用代码
实战问题
13. 如何实现微信小程序的登录授权流程?
答案 :
微信小程序登录授权标准流程:
-
前端检查登录状态:
javascriptwx.checkSession({ success: function() { // session_key未过期,直接使用本地存储的用户信息 }, fail: function() { // session_key已过期,需要重新登录 doLogin(); } })
-
调用wx.login获取code:
javascriptfunction doLogin() { wx.login({ success: res => { if (res.code) { // 发送code到后端换取openid和session_key wx.request({ url: 'https://your.server.com/login', data: { code: res.code }, success: (res) => { // 存储返回的token或session信息 wx.setStorageSync('token', res.data.token) } }) } } }) }
-
获取用户信息(需要用户授权):
javascriptwx.getUserProfile({ desc: '用于完善会员资料', success: (res) => { const userInfo = res.userInfo // 将userInfo发送到后端保存 } })
-
后端处理:
- 使用code调用微信接口
jscode2session
获取openid和session_key - 创建自定义登录态(token)返回给前端
- 存储用户信息
- 使用code调用微信接口
-
后续请求:
- 前端在header中携带token
- 后端验证token有效性
14. uni-app如何实现多端差异化发布?
答案 :
uni-app实现多端差异化发布的方案:
-
条件编译 :
如前所述,使用条件编译为不同平台编写不同代码
-
多入口配置 :
在
pages.json
中配置不同平台的入口:json{ "condition": { "current": 0, "list": [ { "name": "h5", "path": "pages/h5/index", "query": "from=h5" }, { "name": "mp-weixin", "path": "pages/wechat/index", "query": "from=wechat" } ] } }
-
动态配置 :
使用
process.env.UNI_PLATFORM
判断当前平台:javascriptconst platform = process.env.UNI_PLATFORM if (platform === 'h5') { // H5特有逻辑 } else if (platform === 'mp-weixin') { // 微信小程序特有逻辑 }
-
差异化构建 :
在
package.json
中配置不同平台的构建命令:json{ "scripts": { "build:h5": "uni-build --platform h5", "build:mp-weixin": "uni-build --platform mp-weixin" } }
-
manifest.json配置 :
为不同平台配置不同的manifest设置
-
自定义环境变量 :
在
.env
文件中定义不同平台的变量:# .env.h5 VUE_APP_PLATFORM=h5 VUE_APP_API_BASE=https://h5.api.com # .env.mp-weixin VUE_APP_PLATFORM=mp-weixin VUE_APP_API_BASE=https://wechat.api.com
15. 如何解决uni-app或微信小程序中的常见兼容性问题?
答案 :
常见兼容性问题及解决方案:
微信小程序兼容性问题:
-
API兼容性:
- 使用
wx.canIUse
检查API是否可用 - 提供降级方案
- 使用
-
基础库版本差异:
- 在app.json中配置最低基础库版本
json{ "settings": { "miniprogram": { "libVersion": "2.10.0" } } }
-
样式兼容:
- 避免使用部分CSS3新特性
- 使用官方推荐的样式写法
uni-app兼容性问题:
-
平台差异:
- 使用条件编译处理平台差异
- 封装平台兼容的公共方法
-
组件表现不一致:
- 使用uni-ui等跨平台组件库
- 针对不同平台使用不同组件
-
API差异:
- 优先使用uni API而非平台原生API
- 封装兼容层处理API差异
-
样式适配:
- 使用flex布局
- 使用rpx单位
- 避免使用部分平台不支持的选择器
通用解决方案:
-
特性检测:
javascriptfunction isFeatureSupported() { try { // 测试特性是否可用 return true } catch (e) { return false } }
-
渐进增强:
- 先保证基本功能在所有平台可用
- 再为高级平台添加增强功能
-
优雅降级:
- 先实现完整功能
- 再为低版本或低性能平台提供简化方案
-
统一封装:
javascript// 封装兼容的存储API const storage = { set(key, value) { #ifdef MP-WEIXIN wx.setStorageSync(key, value) #endif #ifdef H5 localStorage.setItem(key, JSON.stringify(value)) #endif }, get(key) { // 类似实现... } }