ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

uniapp+Vue3实战教程:从商城前台到后台权限管理

uniapp+Vue3实战教程:从商城前台到后台权限管理 这次我们来看一套 2026 年新版的 uniapp Vue3 全套实战教程。它不只是讲单个页面怎么做而是把前台用户端和后台管理系统串在一起从项目初始化、接口联调到打包上架把一条完整的企业级项目链路走通。对于准备用 uniapp 做跨端应用、同时需要一个 Vue3 后台来管理数据和权限的开发者来说这套内容比零散看文档要高效得多。项目的核心看点有三个第一前台基于 uniapp Vue3 组合式 API 开发一套代码可以跑小程序、H5 和 App第二后台管理系统使用 Vue3 技术栈包含登录、权限、菜单、数据管理等后台必备模块第三接口文档齐全前后端联调时不需要靠猜字段直接按文档对接即可。这套内容对刚入门的人友好对已经在做 Vue2 项目、想切 Vue3 的开发者同样有参考价值。本文会从环境准备开始依次拆解前台商城项目的页面结构、后台管理系统的权限设计、接口文档的联调方式最后补上打包上架和常见问题排查。文章里涉及的命令和代码都是通用示例实际项目中请按自己的目录、请求地址和接口返回结构做调整。1. uniapp Vue3 核心能力速览能力项说明项目类型跨端前台应用 后台管理系统前台技术栈uniapp Vue3 组合式 API后台技术栈Vue3 后台管理系统模板主要功能商城前台、商品展示、订单流程、后台权限管理、数据管理接口文档齐全支持按文档前后端联调支持平台小程序、H5、AppAndroid / iOS适用人群uniapp 入门开发者、Vue2 迁移 Vue3 开发者、全栈学习者学习重点组合式 API、uniapp 生命周期、权限菜单、接口设计、打包上架从学习路径看建议按照“前台搭建 - 接口联调 - 后台管理 - 打包发布”的顺序推进。先跑通前台的基础页面再接入后台的登录和权限体系最后把两端通过接口文档连接起来形成一个完整闭环。2. 适用场景与学习路径这套教程最适合三类人。第一类是刚接触 uniapp 的开发者。uniapp 的核心价值是“一套代码多端运行”但多端运行也意味着要理解条件编译、平台差异、路由规范这些概念。如果直接从文档开始看很容易被碎片化内容带偏。教程把前台页面、组件、路由、请求封装串起来比单独看某个 API 更有效。第二类是正在从 Vue2 迁移到 Vue3 的开发者。Vue3 的组合式 API 和 Vue2 选项式 API 写法差异很大尤其是ref、reactive、computed、watch的使用方式以及script setup语法。后台管理系统这部分能很好地展示 Vue3 在真实项目中的组织方式。第三类是准备做前后端分离项目的全栈学习者。前台用 uniapp 做跨端应用后台用 Vue3 做管理系统接口文档充当两端的契约。这种项目结构非常接近真实公司里的开发模式练完能直接迁移到工作项目中。使用边界方面需要明确几点uniapp 虽然支持多端但不同平台的 API 能力和 UI 表现存在差异业务代码里要通过条件编译做适配后台管理系统的权限设计只是前端控制真正的安全控制必须依赖后端接口的权限校验接口文档中的字段和地址是教程示例接入真实后端时需要按实际接口调整。3. 环境准备与项目初始化3.1 开发工具准备uniapp 开发可以选 HBuilderX 或 CLI 方式两种方式各有特点。HBuilderX 是 DCloud 官方 IDE内置了 uniapp 的编译、运行、发布能力对新手最友好。下载安装后新建项目时直接选择“uniapp”模板语言版本选择 Vue3就可以开始开发。HBuilderX 还集成了小程序模拟器、App 真机运行、云打包等能力不需要额外配置太多环境。CLI 方式适合习惯命令行和团队协作的开发者。项目基于 Vue3 Vite 初始化依赖通过npm或pnpm管理更适合与后端、测试等团队成员保持一致的工具链。无论使用哪种方式都建议先确认 Node.js 环境。CLI 方式下 Node 版本要满足 Vite 的要求通常推荐使用 Node.js 18 及以上版本。HBuilderX 自带的运行环境可以减少一些版本兼容问题但如果做复杂的自定义构建CLI 更灵活。3.2 新建前台项目以 HBuilderX 为例新建项目的操作是这样的。打开 HBuilderX选择“文件 - 新建 - 项目”项目类型选择“uniapp”模板选“默认模板”框架选“Vue3”点击创建即可。项目创建完成后会生成以下核心目录├── pages/ # 页面目录 ├── static/ # 静态资源 ├── App.vue # 应用入口组件 ├── main.js # 入口文件 ├── manifest.json # 应用配置 ├── pages.json # 页面路由与配置 └── uni.scss # 全局样式变量关键配置在manifest.json和pages.json两个文件。manifest.json管理应用名称、appid、小程序配置、App 打包配置等内容pages.json管理页面路由、tabBar、导航栏样式和窗口表现。{ pages: [ { path: pages/index/index, style: { navigationBarTitleText: 首页 } }, { path: pages/category/category, style: { navigationBarTitleText: 分类 } } ], tabBar: { list: [ { pagePath: pages/index/index, text: 首页 }, { pagePath: pages/category/category, text: 分类 } ] } }pages.json里注册的页面路径就是路由地址。uniapp 没有像 Vue Router 那样单独维护路由表页面即路由这一点和传统 Vue3 项目不同需要先适应。3.3 新建后台管理系统后台管理系统建议直接用 Vue3 Vite 初始化。如果不想从零搭建可以使用现成的后台管理系统模板模板一般已经集成了登录页、布局框架、动态路由、权限指令和 Axios 封装能省去很多重复工作。# 使用 Vite 创建 Vue3 项目 npm create vitelatest admin-web -- --template vue cd admin-web npm install npm run dev创建完成后目录结构大致如下├── src/ │ ├── api/ # 接口请求模块 │ ├── components/ # 公共组件 │ ├── layout/ # 后台布局 │ ├── router/ # 路由配置 │ ├── store/ # 状态管理 │ ├── views/ # 页面 │ ├── App.vue │ └── main.js ├── index.html ├── vite.config.js └── package.json后台管理系统的核心不是页面数量而是权限模型、路由守卫和状态管理。登录后拿到 token 和用户角色前端根据角色动态生成可访问的路由再通过路由守卫拦截未登录的访问。这个机制要和后端接口配合确保页面权限和数据权限都受控。4. uniapp 前台商城项目实战从页面到接口4.1 组合式 API 的基本用法uniapp 从 Vue3 开始支持组合式 API在script setup中写逻辑。和 Vue2 的data、methods、computed分块不同Vue3 更强调按业务功能组织代码。script setup import { ref, computed, onMounted } from vue import { getHomeData } from /api/home.js const bannerList ref([]) const goodsList ref([]) const loading ref(false) const totalCount computed(() goodsList.value.length) const loadData async () { loading.value true try { const res await getHomeData() bannerList.value res.data.bannerList goodsList.value res.data.goodsList } finally { loading.value false } } onMounted(() { loadData() }) /script这是最常见的组合式 API 写法。ref用于定义响应式数据computed用于派生状态onMounted是生命周期钩子对应 Vue2 的mounted。在 uniapp 项目里除了 Vue 本身的生命周期还会用到onLoad、onShow等页面生命周期。4.2 uniapp 页面生命周期uniapp 的页面生命周期由框架提供写在script setup中直接引入使用。script setup import { ref } from vue import { onLoad, onShow, onPullDownRefresh, onReachBottom } from dcloudio/uni-app const list ref([]) const page ref(1) onLoad((query) { console.log(页面加载参数, query) loadList() }) onShow(() { console.log(页面显示) }) onPullDownRefresh(() { page.value 1 loadList() uni.stopPullDownRefresh() }) onReachBottom(() { page.value 1 loadList() }) const loadList async () { const res await getGoodsList({ page: page.value }) list.value page.value 1 ? res.data : [...list.value, ...res.data] } /script需要注意页面生命周期的执行顺序onLoad只在页面首次加载时执行onShow每次进入页面都会执行。列表页下拉刷新和触底加载是商城项目的常见需求分页参数要正确维护避免数据重复或遗漏。4.3 请求封装与接口对接前台项目的请求层需要统一封装方便处理 token、错误提示和加载状态。uniapp 中通过uni.request发起请求可以将其封装成一个 Promise 风格的函数。// utils/request.js const BASE_URL https://api.example.com export const request (options) { return new Promise((resolve, reject) { uni.request({ url: BASE_URL options.url, method: options.method || GET, data: options.data || {}, header: { Content-Type: application/json, Authorization: uni.getStorageSync(token) || }, success: (res) { if (res.statusCode 200) { resolve(res.data) } else if (res.statusCode 401) { uni.removeStorageSync(token) uni.navigateTo({ url: /pages/login/index }) reject(res) } else { uni.showToast({ title: res.data.msg || 请求失败, icon: none }) reject(res) } }, fail: (err) { uni.showToast({ title: 网络异常, icon: none }) reject(err) } }) }) }封装后的请求可以按业务模块创建 API 文件比如首页、商品、订单、购物车等。// api/home.js import { request } from /utils/request.js export const getHomeData () { return request({ url: /home/index, method: GET }) } export const getGoodsList (data) { return request({ url: /goods/list, method: POST, data }) }真实项目中接口地址应该通过环境变量管理区分开发环境、测试环境和生产环境。别把接口地址硬编码在页面里否则上线时改起来很痛苦。4.4 商城核心页面拆解一个典型的 uniapp 商城前台会包含这些页面首页轮播图、金刚区入口、推荐商品列表分类页左侧分类导航 右侧商品列表商品列表页排序、筛选、分页商品详情页轮播、价格、规格选择、加购物车购物车页勾选、数量修改、结算订单确认页地址、商品清单、优惠订单列表页订单状态展示、取消、确认收货个人中心页用户信息、订单入口、设置首页推荐用组件拆分轮播图是一个组件商品卡片是一个组件商品列表是一个组件。组件化之后其他页面也能复用商品卡片组件避免重复代码。template view classgoods-card clickgoDetail image classgoods-image :srcgoods.image modeaspectFill / view classgoods-info text classgoods-name{{ goods.name }}/text text classgoods-price¥{{ goods.price }}/text /view /view /template script setup const props defineProps({ goods: { type: Object, required: true } }) const goDetail () { uni.navigateTo({ url: /pages/goods/detail?id${props.goods.id} }) } /script商品详情页的路径参数通过onLoad接收。这个页面通常需要请求详情接口、展示多图轮播、处理规格选择、加入购物车。规格选择是一个独立组件维护一个selectedSpec对象根据用户选择更新价格和库存。5. Vue3 后台管理系统搭建权限与菜单5.1 登录与 token 管理后台管理系统的基本流程是用户输入账号密码请求登录接口后端返回 token 和用户信息前端把 token 存起来之后每次请求都在 header 里带上 token。// store/user.js import { defineStore } from pinia import { loginApi, getUserInfoApi } from /api/user.js export const useUserStore defineStore(user, { state: () ({ token: localStorage.getItem(token) || , userInfo: {} }), actions: { async login(loginForm) { const res await loginApi(loginForm) this.token res.data.token localStorage.setItem(token, res.data.token) return res }, async getUserInfo() { const res await getUserInfoApi() this.userInfo res.data return res.data }, logout() { this.token this.userInfo {} localStorage.removeItem(token) } } })Pinia 是 Vue3 项目的主流状态管理方案比 Vuex 更简洁。在后台管理系统中用户信息、权限列表、菜单列表都可以放在 store 中统一管理。5.2 动态路由与菜单权限后台管理系统的权限控制通常在登录后完成根据用户角色请求菜单接口得到可访问的路由列表然后动态添加路由并生成侧边栏菜单。// router/index.js import { createRouter, createWebHistory } from vue-router import { useUserStore } from /store/user.js const router createRouter({ history: createWebHistory(), routes: [ { path: /login, component: () import(/views/login/index.vue) }, { path: /, component: () import(/layout/index.vue), redirect: /dashboard, children: [] } ] }) router.beforeEach((to, from, next) { const userStore useUserStore() if (to.path /login) { next() return } if (!userStore.token) { next(/login) return } next() }) export default router动态添加路由的方式const addDynamicRoutes (menus) { const routeComponents import.meta.glob(/views/**/*.vue) const buildRoutes (menuList) { return menuList.map(menu { const route { path: menu.path, name: menu.name, meta: { title: menu.title, icon: menu.icon } } if (menu.component) { route.component routeComponents[/src/views/${menu.component}.vue] } if (menu.children menu.children.length) { route.children buildRoutes(menu.children) } return route }) } const dynamicRoutes buildRoutes(menus) dynamicRoutes.forEach(route { router.addRoute(route) }) }菜单接口返回的数据结构要和路由定义保持一致。建议后端直接返回树形结构前端根据这个结构动态生成菜单和路由。这里的关键是路由组件路径要和后端返回的component字段对齐否则会出现页面空白。5.3 后台页面示例商品管理列表后台管理系统最常见的页面是表格页核心功能包括搜索、分页、新增、编辑、删除、状态切换。以商品管理为例template div classproduct-page el-card el-form :inlinetrue :modelqueryForm el-form-item label商品名称 el-input v-modelqueryForm.name placeholder请输入商品名称 clearable / /el-form-item el-form-item label状态 el-select v-modelqueryForm.status placeholder请选择状态 clearable el-option label上架 value1 / el-option label下架 value0 / /el-select /el-form-item el-form-item el-button typeprimary clickhandleSearch查询/el-button el-button clickhandleReset重置/el-button /el-form-item /el-form /el-card el-card el-button typeprimary clickhandleAdd新增商品/el-button el-table :dataproductList v-loadingloading el-table-column propid labelID width80 / el-table-column propname label商品名称 / el-table-column propprice label价格 width120 / el-table-column label状态 width100 template #default{ row } el-tag :typerow.status 1 ? success : info {{ row.status 1 ? 上架 : 下架 }} /el-tag /template /el-table-column el-table-column label操作 width180 template #default{ row } el-button link typeprimary clickhandleEdit(row)编辑/el-button el-button link typedanger clickhandleDelete(row)删除/el-button /template /el-table-column /el-table el-pagination v-model:current-pagequeryForm.page v-model:page-sizequeryForm.pageSize :totaltotal :page-sizes[10, 20, 50] layouttotal, sizes, prev, pager, next, jumper changeloadList / /el-card /div /template表格页的开发节奏通常是先写搜索表单和表格列再写接口请求最后处理分页参数。Element Plus 的表格、表单、弹窗组件封装度比较高适合快速开发后台。如果项目有 API 文档字段名直接对着文档写能减少很多沟通成本。6. 接口文档设计与联调6.1 接口文档的核心内容接口文档是前后端协作的契约一套完整的接口文档应该包含以下内容接口地址和请求方式请求参数参数名、类型、是否必填、说明请求头token、Content-Type返回结果code、message、data 结构错误码说明示例请求和示例响应以商品列表接口为例接口文档通常这样描述POST /api/goods/list 请求头 Authorization: Bearer token 请求参数 { page: 1, pageSize: 10, name: 手机, status: 1 } 返回结果 { code: 200, message: success, data: { list: [ { id: 1, name: 手机, price: 3999, status: 1 } ], total: 100 } }统一的返回结构非常重要。如果后端每个接口的返回结构都不一样前端就得在请求层做大量兼容处理。建议约定一个标准结构比如{ code, message, data }code为 200 表示成功其他为业务错误。6.2 Swagger 与接口文档管理后台管理系统通常用 Swagger 或类似工具管理接口文档。Swagger 可以通过注解自动生成接口文档减少手工维护的成本。Swagger 带来的好处是接口信息实时同步后端接口有变动文档会跟着更新。前端可以直接在 Swagger 页面上查看参数定义和返回结构甚至可以直接复制请求示例。但需要注意Swagger 文档描述的是后端接口的原始定义前端对接时还需要在请求层做二次封装。不要把接口文档里的所有字段都直接暴露给页面组件应该按业务模块在src/api目录下建立独立的接口函数。6.3 前后端联调流程一个标准的联调流程是这样的后端提供 Swagger 或接口文档地址。前端根据文档创建 API 请求模块。本地开发时通过 Vite 或 HBuilderX 的代理配置将接口请求转发到后端测试环境。联调过程中如果发现字段缺失或返回结构不一致及时和后端确认并更新文档。联调完成后将接口地址切换到生产环境再做一轮全量回归。uniapp 前台和后台管理系统是两个独立项目但接口文档是同一个。也就是说前台商城和后台商品的增删改查操作的是同一套后端接口数据只是入口不同。这正好解释了为什么这套教程要把前台和后台放在一起学它能直观展示一套接口如何支撑两个前端应用。7. 项目打包与上线7.1 uniapp 打包为微信小程序在 HBuilderX 中选择“运行 - 运行到小程序模拟器 - 微信开发者工具”即可将 uniapp 项目编译为微信小程序并自动打开微信开发者工具。首次使用需要在小程序开发工具中配置 AppID。如果只是本地预览可以使用测试号。如果需要真机预览或发布需要注册小程序账号并获取正式 AppID。发布步骤是在微信开发者工具中点击“上传”填写版本号和备注然后到微信公众平台的版本管理页面提交审核审核通过后发布上线。7.2 uniapp 打包为 Appuniapp 打包 App 有两种方式云打包和本地打包。云打包不需要本地配置 Android SDK 和 iOS 环境直接在 HBuilderX 中点击“发行 - 原生App-云打包”选择 Android 或 iOS 平台即可。云打包需要 DCloud 开发者账号支持使用公共证书或自定义证书。本地打包需要在 manifest.json 中配置 SDK 版本然后下载对应平台的离线 SDK 进行集成。本地打包更适合需要对原生代码做定制的团队比如接入特定的原生插件或推送 SDK。App 打包完成后Android 会生成 APK 或 AAB 文件iOS 需要上架 App Store审核流程在小程序平台之外。7.3 后台管理系统部署后台管理系统是 Vue3 项目构建后得到的是静态文件可以部署到 Nginx、Tomcat 或对象存储服务上。# 构建生产环境代码 npm run build构建产物在dist目录中。以 Nginx 为例部署配置如下server { listen 80; server_name admin.example.com; root /var/www/admin; index index.html; location / { try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }这里的关键配置是try_files $uri $uri/ /index.html作用是让所有路由都指向index.html由前端路由接管页面跳转。否则刷新一个二级路由页面会出现 404。8. 资源占用与性能观察8.1 uniapp 前台性能观察uniapp 项目在开发阶段运行在模拟器中时CPU 和内存占用取决于编译工具和模拟器的开销。HBuilderX 开发和微信开发者工具同时开启时内存占用会比较高建议开发机上保留 16GB 以上内存。前台性能优化的重点不在开发工具而在运行时表现。pages.json中注册的页面数量、首页请求数量、图片资源大小都会影响小程序的启动速度。关注这几个指标首页首屏请求数量控制在 5 个以内图片大小使用压缩后的图片建议单张不超过 200KB页面切换耗时通过onShow和onLoad打印日志查看8.2 Vue3 后台性能观察后台管理系统是浏览器端应用性能观察主要看页面加载速度和接口响应时间。打开 Chrome DevTools 的 Network 面板可以查看每个接口的耗时和资源加载情况。后端管理系统的性能瓶颈通常在大列表页面。如果商品列表数据量过大需要后端做分页和过滤前端不要一次性加载所有数据。表格超过 100 行时建议使用虚拟滚动。实际占用数据需要在各自环境中测试启动多个前端项目、后端服务和浏览器后观察任务管理器中的 CPU 和内存占用根据项目规模调整开发机配置。9. 常见问题与排查方法问题现象可能原因排查方式解决方案页面跳转显示 not found:pagepages.json 中未注册页面路径检查 pages.json 的 pages 数组在 pages.json 中添加对应页面路径HBuilderX 运行微信小程序失败微信开发者工具未开启服务端口打开微信开发者工具设置开启服务端口在微信开发者工具中开启安全设置的服务端口vue3 项目在浏览器中无法正常显示端口被占用或路由配置错误查看命令行日志检查端口和路由更换端口或检查路由配置后台管理系统刷新后 404Nginx 未配置 try_files检查 Nginx 配置配置try_files $uri $uri/ /index.html接口请求 401token 过期或未携带查看请求 header 中 Authorization重新登录获取 token检查请求封装uni.request 请求失败接口地址错误或跨域查看浏览器/小程序控制台错误检查 BASE_URLH5 端配置代理批量任务或分页加载卡住分页参数维护错误检查 page 和 pageSize 参数修正分页逻辑避免死循环依赖安装失败Node 版本不兼容查看 npm 报错信息升级或降级 Node 版本换用 pnpmApp 云打包失败manifest.json 配置不完整检查 AppID、证书配置补全配置使用公共证书测试打包前端字段和接口文档不一致接口文档未更新对照 Swagger 或接口文档确认和后端确认字段更新文档上面这些问题是开发过程中最高频的几类。uniapp 项目中not found:page是新手最容易遇到的原因是pages.json里的路径没有写对。后台管理系统中刷新 404 是部署阶段最容易踩的坑原因是 Nginx 没有做前端路由的 fallback 配置。10. 最佳实践与建议10.1 前台项目推荐做法页面目录按业务模块划分不要把所有页面都堆在 pages 根目录下。请求层统一封装不要在页面里直接调用uni.request。多端差异用条件编译处理不要用大量 if 判断平台。公共组件抽出来商品卡片、图片上传、规格选择都是高频组件。图片资源做压缩必要时使用 CDN。tabBar 页面使用uni.switchTab跳转普通页面使用uni.navigateTo。10.2 后台项目推荐做法权限控制用动态路由菜单和路由由后端接口下发。token 过期后统一跳转登录页不要在页面里各自处理。大列表页面用分页和筛选不要一次加载全量数据。Pinia 中只放跨页面共享的状态页面局部状态不要都塞进 store。接口请求函数按模块组织一个页面一个 API 文件方便维护。10.3 接口联调建议接口文档里统一返回结构{ code, message, data }不要混用。请求封装里集中处理 401、403、网络异常等通用错误。开发环境用代理解决跨域不要在浏览器里禁用安全策略。字段命名保持统一建议后端使用小驼峰。联调过程中发现问题先确认是不是文档过期再排查代码逻辑。10.4 合规与安全提醒后台管理系统涉及用户数据、订单数据等敏感信息时必须在接口层面做权限校验。前台商城涉及用户支付、地址、手机号等信息需要明确隐私政策并告知用户。不要在前端代码中硬编码后端密钥、数据库连接信息等敏感配置。上架到各大应用市场和小程序平台时需要提供符合平台要求的软件著作权证明、隐私协议等材料。如果接入第三方地图、支付、推送服务遵守对应平台的合规要求。11. 总结与后续建议这套 uniapp Vue3 前后台教程最值得尝试的点是把前台跨端应用和后台管理系统放进同一个项目框架里配合完整接口文档让学习者能真正理解一个企业级项目是怎么协作的。新开发者在完整实现前台页面和后台权限后会对 uniapp 的多端运行逻辑和 Vue3 的组合式 API 形成系统认知而不是只停留在看文档的阶段。刚开始实践时建议先从小程序端前台做起把首页、商品列表、商品详情这条主链路跑通然后搭建后台管理的登录和动态路由最后再让两个项目对接同一套接口。先小范围验证再逐步加功能。过程中最容易踩的坑有两个一是 uniapp 页面路由和pages.json配置不一致导致跳转失败二是后台管理系统部署后刷新 404。这两个问题在本文的排查清单中已经有对应方案建议收藏备用。后续如果时间充裕可以继续扩展这些方向给前台加上登录功能、购物车逻辑和在线支付给后台加上角色管理、操作日志和数据统计将接口文档接入自动化测试在 HBuilderX 中完成 App 云打包并上架应用市场。把这套链路完整走完基本就掌握了 uniapp Vue3 在企业项目中的主流开发模式。
返回列表