uni-app 面试知识点梳理

uni-app 面试知识点梳理

    • 一、基础认知(必问)
      • [1.1 一句话定义](#1.1 一句话定义)
      • [1.2 跨端原理(高频)](#1.2 跨端原理(高频))
      • [1.3 uni-app 与 Vue 的关系](#1.3 uni-app 与 Vue 的关系)
      • [1.4 Vue2 与 Vue3 选型(面试加分点)](#1.4 Vue2 与 Vue3 选型(面试加分点))
    • 二、项目结构与配置
      • [2.1 标准目录](#2.1 标准目录)
      • [2.2 pages.json(核心配置,必会)](#2.2 pages.json(核心配置,必会))
      • [2.3 标签映射(易踩坑)](#2.3 标签映射(易踩坑))
    • 三、生命周期(高频重灾区)
      • [3.1 三层生命周期](#3.1 三层生命周期)
      • [3.2 页面 vs 组件生命周期执行顺序(经典题)](#3.2 页面 vs 组件生命周期执行顺序(经典题))
      • [3.3 onLoad 与 onShow 区别(必背)](#3.3 onLoad 与 onShow 区别(必背))
    • 四、路由与跳转
      • [4.1 五种跳转 API](#4.1 五种跳转 API)
      • [4.2 传参与接收](#4.2 传参与接收)
      • [4.3 路由拦截](#4.3 路由拦截)
    • 五、网络请求与封装(实战必考)
      • [5.1 原生请求](#5.1 原生请求)
      • [5.2 面试级封装要点](#5.2 面试级封装要点)
      • [5.3 文件上传/下载](#5.3 文件上传/下载)
    • [六、状态管理(Vuex / Pinia)](#六、状态管理(Vuex / Pinia))
      • [6.1 何时需要](#6.1 何时需要)
      • [6.2 Vuex 经典结构](#6.2 Vuex 经典结构)
      • [6.3 Pinia(Vue3 推荐)](#6.3 Pinia(Vue3 推荐))
      • [6.4 跨页传值替代方案](#6.4 跨页传值替代方案)
    • [七、条件编译(uni-app 特色,必考)](#七、条件编译(uni-app 特色,必考))
      • [7.1 语法](#7.1 语法)
      • [7.2 各位置写法](#7.2 各位置写法)
      • [7.3 常用平台标识](#7.3 常用平台标识)
    • 八、小程序专项(结合实际项目重点)
      • [8.1 登录流程(微信小程序必考)](#8.1 登录流程(微信小程序必考))
      • [8.2 分包加载(性能关键)](#8.2 分包加载(性能关键))
      • [8.3 rpx 单位](#8.3 rpx 单位)
      • [8.4 微信支付](#8.4 微信支付)
    • [九、组件通信(Vue 通用 + uni 特有)](#九、组件通信(Vue 通用 + uni 特有))
      • [9.1 通信方式对比](#9.1 通信方式对比)
      • [9.2 组件生命周期在 uni 中的注意点](#9.2 组件生命周期在 uni 中的注意点)
    • 十、性能优化(高频)
    • 十一、易踩坑清单(实战血泪)
    • [十二、uni-app X 与新趋势(加分)](#十二、uni-app X 与新趋势(加分))
    • [十三、高频面试题 30 连击(自测)](#十三、高频面试题 30 连击(自测))
    • [附:答题模板(STAR 简化版)](#附:答题模板(STAR 简化版))

定位:求职技术岗(uni-app / 小程序前端)面试速通。

范围:以微信小程序 为主战场,兼顾 H5 / App。Vue2 + Vue3 双栈覆盖。

用法:每个模块先看"核心结论",再看"面试题",最后对照"易踩坑"。


一、基础认知(必问)

1.1 一句话定义

uni-app 是 DCloud 出品的、基于 Vue 语法的跨端应用框架,一套代码可编译到微信/支付宝/百度/抖音小程序、H5、App(iOS/Android)、快应用等。

1.2 跨端原理(高频)

作用 说明
编译器(cli/ide) 把 Vue SFC 编译成各平台目标代码 小程序:.vuewxml/wxss/js/json;H5:标准 Vue;App:weex/uts
运行时(runtime) 抹平各平台 API 差异 uni.xxx 调用在底层映射到 wx.xxx / navigator / plus
条件编译 差异化代码 #ifdef MP-WEIXIN ... #endif

关键结论 :uni-app = Vue 语法 + 平台编译器 + 统一运行时。它不是"套壳 webview",小程序端是原生组件渲染

1.3 uni-app 与 Vue 的关系

  • 模板、数据绑定、组件、生命周期沿用了 Vue
  • 小程序平台下没有 DOM/BOMdocumentwindowlocalStorage 在小程序端不存在 → 必须用 uni.xxx 替代。
  • Vue3 版本使用 Vite 编译,性能与 Tree-shaking 更优;Vue2 版本逐步进入维护态。

1.4 Vue2 与 Vue3 选型(面试加分点)

维度 Vue2(Options) Vue3(Composition + Vite)
编译器 vue-cli / HbuilderX Vite(更快)
响应式 Object.defineProperty Proxy
写法 data(){return{}} / methods setup() / <script setup>
状态管理 Vuex Pinia(官方推荐)
兼容性 老项目多 新项目首选

二、项目结构与配置

2.1 标准目录

复制代码
├─ pages/            # 页面(每个页一个文件夹)
│  ├─ index/index.vue
├─ components/       # 自定义组件
├─ static/           # 静态资源(图片等,不被编译)
├─ store/            # Vuex/Pinia
├─ utils/            # 工具(request 封装等)
├─ App.vue           # 应用入口(应用生命周期)
├─ main.js           # 入口脚本
├─ pages.json        # ★ 路由 + 全局样式 + 分包配置
├─ manifest.json     # 应用配置(appid、名称、图标)
└─ uni.scss          # 全局样式变量

2.2 pages.json(核心配置,必会)

json 复制代码
{
  "pages": [
    { "path": "pages/index/index", "style": { "navigationBarTitleText": "首页" } }
  ],
  "globalStyle": { "navigationBarBackgroundColor": "#007AFF" },
  "tabBar": {
    "list": [
      { "pagePath": "pages/index/index", "text": "首页", "iconPath": "..." }
    ]
  },
  "subPackages": [
    { "root": "packageA", "pages": [{ "path": "list/list" }] }
  ],
  "preloadRule": {
    "pages/index/index": { "network": "all", "packages": ["packageA"] }
  }
}

面试题pages 数组第一项是什么?→ 应用启动页(首页)。

2.3 标签映射(易踩坑)

HTML uni-app
<div> <view>
<span> <a> <text>
<img> <image>
<input> <input> / <textarea>
<ul><li> 无,用 <view> 模拟

注意:<text> 内只能嵌套文本/文本组件,放 <view> 不生效。


三、生命周期(高频重灾区)

3.1 三层生命周期

层级 钩子 触发时机
应用级(App.vue) onLaunch 应用初始化(全局一次)
应用级 onShow / onHide 应用前台/后台
页面级 onLoad(options) 页面加载(传参在这里接收)
页面级 onShow / onReady / onHide / onUnload 显示/渲染完成/隐藏/卸载
组件级(Vue2) created/mounted 同 Vue
组件级(Vue3) onMounted 等(需 import) 组合式

3.2 页面 vs 组件生命周期执行顺序(经典题)

复制代码
页面 onLoad → 组件 created → 组件 mounted → 页面 onReady
  • 页面 onLoad 早于组件 mounted
  • 页面切走:onHide;再回来:onShow(组件不重新创建,故 created 不重复)。

3.3 onLoad 与 onShow 区别(必背)

  • onLoad:页面创建时 执行一次,适合初始化、options 取参。
  • onShow:每次显示都执行,适合刷新数据(如从详情页返回列表需刷新)。

四、路由与跳转

4.1 五种跳转 API

API 表现 是否可返回 栈上限
navigateTo 打开新页 10 层
redirectTo 替换当前页 ---
switchTab 跳 tabBar 页 ---
reLaunch 关闭所有重开 ---
navigateBack 返回 --- ---

易踩坑

  • switchTab 不能传参(URL 参数会被忽略),跨 tab 传值要用全局状态/本地缓存。
  • navigateTo 超过 10 层会失败,需 redirectToreLaunch 兜底。

4.2 传参与接收

js 复制代码
// A 页
uni.navigateTo({ url: '/pages/detail/detail?id=123&name=test' })

// B 页 onLoad
onLoad(options) {
  console.log(options.id, options.name) // '123' 'test'(均为字符串)
}

接收值永远是字符串 ,数字需 Number() 转换。

4.3 路由拦截

  • 全局:在 App.vueonShow 中根据 uni.getLaunchOptionsSync() / 页面栈做权限判断。
  • 推荐用 uni.addInterceptor('navigateTo', {...}) 做统一登录校验(实战常用)。

五、网络请求与封装(实战必考)

5.1 原生请求

js 复制代码
uni.request({
  url: 'https://api.example.com/list',
  method: 'GET',
  data: { page: 1 },
  header: { 'Authorization': token },
  success: (res) => {},
  fail: (err) => {}
})

5.2 面试级封装要点

  1. Promise 化 :用 return new Promise 包裹,支持 async/await
  2. 拦截器:请求前注入 token,响应后统一处理 401/状态码。
  3. 错误统一处理:网络错误、业务错误码分层。
  4. baseURL 环境切换:dev / prod 通过条件编译或 env 区分。
js 复制代码
// utils/request.js 简化版
const BASE_URL = 'https://api.example.com'
export function request(options) {
  return new Promise((resolve, reject) => {
    uni.request({
      url: BASE_URL + options.url,
      method: options.method || 'GET',
      data: options.data,
      header: { 'Authorization': uni.getStorageSync('token') || '' },
      success: (res) => {
        if (res.statusCode === 200 && res.data.code === 0) resolve(res.data)
        else if (res.data.code === 401) { uni.navigateTo({url:'/pages/login/login'}); reject(res.data) }
        else reject(res.data)
      },
      fail: reject
    })
  })
}

5.3 文件上传/下载

  • 上传:uni.uploadFile({ url, filePath, name:'file', formData })
  • 下载:uni.downloadFile → 拿到临时路径 → uni.saveFile
  • 小程序端不能直接操作本地文件系统路径,只能拿到临时路径。

六、状态管理(Vuex / Pinia)

6.1 何时需要

  • 跨页面共享(用户信息、登录态、购物车)。
  • 全局配置(主题、地区)。

6.2 Vuex 经典结构

js 复制代码
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
  state: { token: '' },
  mutations: { setToken(s, v){ s.token = v } },
  actions: { login({commit}, payload){ /* 异步 */ commit('setToken', payload) } },
  getters: { isLogin: s => !!s.token }
})

6.3 Pinia(Vue3 推荐)

  • mutationsstate/actions/getters 更直接。
  • 天然支持 Composition API,storeToRefs 解构保持响应性。

6.4 跨页传值替代方案

场景 方案
兄弟/跨多级页 Vuex/Pinia
简单临时 uni.setStorageSync
页面栈直取 getCurrentPages() 取上一页 setData

七、条件编译(uni-app 特色,必考)

7.1 语法

js 复制代码
// #ifdef MP-WEIXIN
console.log('只在微信小程序编译')
// #endif

// #ifndef H5
console.log('除了 H5 都编译')
// #endif

// 多平台
// #ifdef MP-WEIXIN || MP-ALIPAY

7.2 各位置写法

位置 写法
模板 <!-- #ifdef MP-WEIXIN -->
样式 /* #ifdef MP-WEIXIN */
脚本 // #ifdef MP-WEIXIN

7.3 常用平台标识

MP-WEIXIN MP-ALIPAY MP-BAIDU MP-TOUTIAO H5 APP-PLUS APP MP(所有小程序)。


八、小程序专项(结合实际项目重点)

8.1 登录流程(微信小程序必考)

复制代码
1. 前端 uni.login() → 拿到 code
2. 把 code 发给后端
3. 后端用 code + appsecret 调微信接口换 openid/session_key
4. 后端生成自定义 token 返回前端
5. 前端存 token,后续请求携带

注意:code 只能用小程序的 wx.login/uni.login 换,不能前端直接拿 openid(安全)。

8.2 分包加载(性能关键)

  • 主包过大(微信限制 2MB 主包)会导致无法预览/上传 → 必须分包。
  • 分包通过 subPackages 配置,独立打包,使用时按需下载。
  • 分包预下载 preloadRule 优化首跳体验。

8.3 rpx 单位

  • 750rpx = 屏幕宽度,自适应各机型。
  • 设计稿通常按 750px 出图,1:1 写 rpx。
  • 注意:rpx 有个别机型 rounding 误差,关键尺寸可用 px 兜底。

8.4 微信支付

  • 前端:uni.requestPayment({ provider:'wxpay', timeStamp, nonceStr, package, signType, paySign })
  • 参数由后端统一下单生成,前端只负责调起。

九、组件通信(Vue 通用 + uni 特有)

9.1 通信方式对比

方式 适用 说明
props / $emit 父子 标准
provide / inject 跨层 Vue 原生
uni.$on / uni.$emit 任意组件 uni 事件总线 ,需 uni.$off 销毁防内存泄漏
Vuex/Pinia 全局 状态
ref 父调子方法 this.$refs.child.fn()

9.2 组件生命周期在 uni 中的注意点

  • 小程序组件无 onShow,只有 Vue 的 created/mounted 等。
  • 需监听页面显示时,用 uni.$on('pageShow') 在页面 onShow 中触发。

十、性能优化(高频)

  1. 分包:控制主包 < 2MB。
  2. 图片 :用 CDN + 压缩,避免本地大图;lazy-load 懒加载。
  3. 长列表 :数据量大用 uni.createIntersectionObserver 或虚拟列表,避免一次性渲染。
  4. v-for 必须 key:用稳定 id,不用 index(小程序重排 bug)。
  5. 减少 setData 频率/体积:小程序 setData 有性能成本,合并数据、避免传大对象。
  6. onLoad 初始化 / onShow 轻量刷新 :别在 onShow 做重活。
  7. 组件按需引入:非全局组件局部注册。

十一、易踩坑清单(实战血泪)

现象 解决
小程序无 window/document 报错 undefined 用 uni API 替代
switchTab 传参无效 收不到 用 storage/store
页面栈超 10 层 navigateTo 失败 redirectTo/reLaunch
rpx 误差 个别机型错位 关键尺寸 px
事件总线未 off 重复触发 页面 onUnload 中 $off
本地图片过大 主包超限 转 CDN / 分包
H5 端跨域 请求失败 配 proxy 或后端 CORS
真机与模拟器差异 样式/API 不一致 必须真机调试
v-if 与 v-for 同元素 警告/逻辑错 拆开或用 computed 过滤
自定义组件样式隔离 外部样式不生效 options:{styleIsolation:'shared'}::v-deep

十二、uni-app X 与新趋势(加分)

  • uni-app x :用 uts(TypeScript 风格)直接编译为原生(Kotlin/Swift),性能接近原生,但生态尚在完善。
  • Vue3 + Vite 已成新项目默认。
  • uniCloud:DCloud 的 serverless,前后端一体。
  • 面试时如能对比"传统编译型 vs uni-app x 原生型"体现技术视野。

十三、高频面试题 30 连击(自测)

  1. uni-app 跨端原理是什么?
  2. Vue2 和 Vue3 在 uni-app 中的区别?
  3. 页面生命周期与组件生命周期执行顺序?
  4. onLoad 和 onShow 的区别与适用场景?
  5. 小程序为什么没有 DOM?如何替代?
  6. 五种路由 API 及使用区别?
  7. switchTab 为什么不能传参?怎么解决?
  8. 页面栈上限是多少?超限怎么办?
  9. 如何封装 uni.request?
  10. 401 怎么统一处理?
  11. 微信小程序登录流程?
  12. code 能在前端直接换 openid 吗?为什么?
  13. 什么是分包?为什么要分包?主包限制?
  14. 分包预下载有什么用?
  15. rpx 是什么?设计稿怎么对应?
  16. 条件编译语法?常用平台标识?
  17. 如何在 H5 和小程序写不同代码?
  18. Vuex 和 Pinia 区别?uni 推荐哪个?
  19. 跨页面传值有哪些方式?
  20. uni.$on 需要注意什么?
  21. 父子组件通信方式?
  22. provide/inject 适用场景?
  23. 小程序支付流程?谁生成签名?
  24. 如何做路由拦截/登录校验?
  25. 长列表如何优化?
  26. setData 为什么有性能成本?如何优化?
  27. v-for 为什么必须 key?能用 index 吗?
  28. 真机调试为什么必要?
  29. 事件总线内存泄漏怎么避免?
  30. uni-app x 相比传统方案优势?

附:答题模板(STAR 简化版)

被问原理类 :先一句话结论 → 再讲分层/流程 → 举项目中的例子。

被问优化类:先说现象/指标 → 再给手段(分包/懒加载/合并 setData)→ 讲你项目里做到了哪一步。

相关推荐
沉默王二31 分钟前
豆包工作Agent正式发布,直接给到夯。
人工智能·面试·agent
怕浪猫7 小时前
第 1 章 FDE的崛起
面试
郑州光合科技余经理13 小时前
本地生活服务系统:模块边界与结算字段怎么拆
java·开发语言·前端·后端·系统架构·uni-app·php
怕浪猫17 小时前
用了两年 AI 编程工具后,我重新理解了什么是「资深工程师」
算法·面试·架构
ychqsq18 小时前
144.扎根
经验分享·职场和发展
阿宁学科技术库1 天前
关于“库库AI”在股票投研场景实用性的技术观察
大数据·人工智能·职场和发展
evans在进步1 天前
LeetCode 238 除自身以外数组的乘积:前缀积与后缀积详解
算法·leetcode·职场和发展
Brilliantwxx1 天前
【C++】初入嵌入式C++复习-----经典面试题100道
开发语言·c++·算法·面试·职场和发展
蒸蒸yyyyzwd1 天前
cpp 选手备战秋招学习笔记 day19
面试·求职招聘