前端小程序面试题
说说微信小程序的生命周期函数有哪些?
三类生命周期:
- 应用级:
App()
注册(全局) - 页面级:
Page()
注册(单页面) - 组件级:
Component()
注册(自定义组件)
应用生命周期(app.js)
函数 | 触发时机 |
---|---|
onLaunch | 初始化完成(全局一次) |
onShow | 启动或从后台进入前台 |
onHide | 从前台进入后台 |
onError | 脚本错误或API报错 |
onPageNotFound | 页面不存在 |
onUnhandledRejection | 未处理的Promise拒绝 |
onThemeChange | 系统切换主题 |
页面生命周期
函数 | 说明 | 典型用途 |
---|---|---|
onLoad | 页面加载 | 发送请求获取数据 |
onShow | 页面显示 | 请求数据 |
onReady | 页面初次渲染完成 | 获取页面元素(少用) |
onHide | 页面隐藏 | 终止定时器/音乐 |
onUnload | 页面卸载 | 清理任务 |
组件生命周期
函数 | 触发时机 |
---|---|
created | 组件实例创建(不可用setData ) |
attached | 组件插入节点树(初始化主时机) |
ready | 组件渲染完成 |
moved | 组件移动 |
detached | 组件移出节点树 |
error | 组件方法报错 |
执行顺序
应用启动:
App.onLaunch → App.onShow → Page.onLoad → Page.onShow → Page.onReady
页面跳转:
当前页onHide → 新页onLoad → onShow → onReady
返回上一页:
当前页onUnload → 上一页onShow
微信小程序的登录流程?
- 传统登录:账号密码/短信验证 → 服务端返回Token
- 小程序登录:通过微信身份标识快速建立用户体系,核心元素:code:临时凭证(wx.login()获取)、openid:用户在小程序的唯一ID
关键步骤
- 小程序调用 wx.login() 获取 code
- 后端用 appid + appsecret + code 请求微信接口
- 微信返回 session_key 和 openid
- 后端生成 3rd_session(关联 openid 和 session_key)
- 小程序存储 3rd_session 并后续请求携带
- 后端校验 3rd_session 有效性
登录态校验
- 方案1:服务端校验有效期(需网络请求)
- 方案2:调用 wx.checkSession()(无网络消耗):
微信小程序中路由跳转的方式有哪些?区别?
核心机制
- 页面栈管理:最多10层页面栈
- 每个页面是一个 pageModel
跳转方式对比
方法 | 作用 | 页面栈变化 | 特点 |
---|---|---|---|
wx.navigateTo | 保留当前页,跳转新页面 | 新页面入栈 | 可返回原页 |
wx.redirectTo | 关闭当前页,跳转新页面 | 当前页出栈 → 新页入栈 | 不可返回 |
wx.switchTab | 跳转 Tab 页,关闭所有非 Tab 页 | 非 Tab 页全出栈 → Tab 页入栈 | 仅用于 TabBar 页面 |
wx.navigateBack | 返回上一页或多级页面 | 页面出栈直到目标页 | 可设置 delta 参数 |
wx.reLaunch | 关闭所有页,打开新页面 | 所有页出栈 → 新页入栈 | 返回时跳到首页 |
小程序页面间传值方法详解
URL 参数传递(适合简单数据)
- 通过 wx.navigateTo 或 wx.redirectTo 的 url 参数传递
- 在目标页面的 onLoad 生命周期函数中获取
只支持字符串类型
URL长度有限制(不能超过一定长度)
// 页面A跳转并传值
wx.navigateTo({url: '/pages/pageB/pageB?id=123&name=test'
})// 页面B接收
Page({onLoad: function(options) {console.log(options.id) // 输出: 123console.log(options.name) // 输出: test}
})
全局变量(适合多页面共享数据)
- 在 app.js 中定义全局变量
- 通过 getApp() 方法获取应用实例
不是响应式的,需要手动触发更新
适合存储用户信息等全局数据
// app.js
App({globalData: {userInfo: null,token: ''}
})// 任何页面获取/设置
const app = getApp()
app.globalData.token = 'abc123' // 设置
console.log(app.globalData.token) // 获取
本地存储(适合需要持久化的数据)
- 使用 wx.setStorageSync/wx.getStorageSync 或异步API
数据持久化,关闭小程序后仍然存在
有容量限制(10MB)
同步操作可能阻塞UI
// 存储数据
wx.setStorageSync('key', 'value')// 获取数据
const value = wx.getStorageSync('key')
事件总线(适合组件间通信)
- 使用 getCurrentPages() 获取页面栈
- 通过页面实例直接调用方法
适合页面返回时传值
需要确保页面栈中存在目标页面
// 获取前一个页面实例
const pages = getCurrentPages()
const prevPage = pages[pages.length - 2]// 调用前一个页面的方法
prevPage.setData({ message: '来自下一页的消息' })
EventChannel(页面间通信)
- 通过 wx.navigateTo 的 events 配置建立通信
- 使用 this.getOpenerEventChannel() 获取EventChannel实例
支持双向通信
适合需要持续通信的场景
// 页面A
wx.navigateTo({url: '/pages/pageB/pageB',events: {acceptData: function(data) {console.log(data) // 接收来自页面B的数据}},success: function(res) {res.eventChannel.emit('sendData', {data: '来自页面A'}) // 向页面B发送数据}
})// 页面B
Page({onLoad: function(options) {const eventChannel = this.getOpenerEventChannel()eventChannel.on('sendData', (data) => {console.log(data) // 接收来自页面A的数据})// 向页面A发送数据eventChannel.emit('acceptData', {data: '来自页面B'})}
})
bindtap 与 catchtap 对比说明
特性 | bindtap | catchtap |
---|---|---|
事件冒泡 | 允许事件继续向父节点冒泡 | 阻止事件继续向父节点冒泡 |
使用场景 | 需要父组件也响应点击事件时使用 | 需要阻止事件冒泡时使用 |
性能影响 | 可能有更多的事件处理函数被调用(多级冒泡) | 更高效,只触发当前组件的事件处理函数 |
bindtap:绑定的事件处理函数执行后,事件会继续向父组件冒泡 点击按钮时,会先触发 childTap,然后触发 parentTap
<view bindtap="parentTap"><button bindtap="childTap">点击我</button>
</view>
catchtap:绑定的事件处理函数执行后,会阻止事件继续冒泡 点击按钮时,只会触发 childTap,不会触发 parentTap
<view bindtap="parentTap"><button catchtap="childTap">点击我</button>
</view>
实际应用场景
- 使用 bindtap 的情况:
需要父子组件都能响应点击事件时
需要利用事件冒泡机制实现某些功能时
- 使用 catchtap 的情况:
阻止事件冒泡,避免父组件意外触发 提高性能,
减少不必要的事件处理
实现点击穿透阻止(如防止遮罩层下的内容被点击)
小程序的兼容问题有哪些
1. iOS 下 z-index 层级问题
- 问题描述:多个绝对定位元素在 iPhone7、iPhoneX 下可能出现层级错乱。
- 解决方案:确保所有绝对定位元素具有同一个共同的父元素。
2. 键盘遮挡输入框(iOS)
- 问题描述:输入框被系统键盘遮挡。
- 解决方案:开启
adjustPosition
,或页面滚动处理。
…
小程序支付流程
在微信小程序中,bindtap 和 catchtap 都是用于处理点击事件的事件绑定方式,但它们的关键区别在于事件冒泡的处理机制。
- 打开电商小程序点击下单
- wx.login获取用户临时登录凭证凑得,发送到后端换取openId
- 下单时小程序需要将购买的商品id,商品数量,以及用户的openId发送给服务器
- 服务器在接收到这些参数后,商城服务器订单数据,同时经过签名算法向微信支付发送请求,获取预付单的信息,同时将获取的数据再次进
- 行相对规则的签名,向小程序端响应必要的参数
- 小程序端在拿到对应的参数后,调用wx.requestPayment()发起 微信支付,唤醒支付工作台进行支付
- 接下来的一系列操作都是用户来操作,支付密码、指纹、等验证确认支付成功后执行鉴权调启支付
- 微信后台进行健全,在微信后台直接返回给前端支付结果,前端收到了返回的数据后对支付结果进行展示。
微信小程序首屏渲染优化手段
控制代码包大学校
分包加载
首屏数据预请求,数据缓存、避免白屏、用户操作及时反馈
- 请求可以在页面onLoad的时候就加载,减少不必要的https请求,可以用egtSotrageSync等方法将树存储在本地
- 可以在前置页面将一些有用的字段带到当前页面,
- 没有数据的模块可以用骨架伞占位
- 不要过于频繁的使用setData,可以考虑将多次setData合并成一次
…
是最近面试的时候问的的一些问题,目前还在面试中,持续更新ing
点个👍哇~