UniApp + Vue3 + TS 工程化实战笔记
UniApp + Vue3 + TS 工程化实战笔记
一、为什么要用 CLI 而不是 HBuilderX?
| 维度 |
HBuilderX |
CLI + Vscode |
| TS 类型推导 |
❌ 经常报红 |
✅ 丝滑 |
| 依赖管理 |
内置、黑盒 |
可见、可锁版本 |
| 工程化扩展 |
受限 |
随便玩 Vite 插件 |
| 团队协作 |
需要统一 IDE |
任意编辑器 |
⚠️ 用 HBuilderX 创建后再拖到 Vscode,90% 会遭遇「找不到模块」爆红,CLI 模板一步到位。
二、极速创建项目
1 2 3 4 5 6 7
| npx degit dcloudio/uni-preset-vue cd my-vue3-project
yarn
|
三、Vscode 必备插件清单
| 插件 |
作用 |
必装 |
| Vue - Official |
Vue3 语法高亮 |
✅ |
| uni-create-view |
右键一键生成页面 |
✅ |
| uni-helper |
代码片段 & 提示 |
✅ |
| uni-highlight |
.uvue 高亮 |
✅ |
| uniapp小程序扩展 |
微信/阿里 API 提示 |
✅ |
⚠️ Vue - Official ≥2.x 会对小程序自定义组件误报,关闭「Vue › Validation: Template」或回退到 1.8 即可。
四、封装「零依赖」HTTP 请求层
特点:
- 自动携带
token & platform 头
- 401 自动清缓存 & 跳转登录页
- 后端字段容错(
error / message / data)
- 返回 Promise,直接
await
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| export const http = <T>(options: UniApp.RequestOptions) => new Promise<Data<T>>((resolve, reject) => { uni.request({ ...options, url: options.url.startsWith('http') ? options.url : baseURL + options.url, header: { platform: 'miniapp', Authorization: uni.getStorageSync('token') || '', ...options.header, }, success: ({ statusCode, data }) => { if (statusCode >= 200 && statusCode < 300) return resolve(data as Data<T>); if (statusCode === 401) { uni.clearStorage(); uni.navigateTo({ url: '/pages/login/login' }); } uni.showToast({ icon: 'none', title: (data as any)?.error || (data as any)?.message || '请求异常', }); reject(data); }, fail: () => { uni.showToast({ icon: 'none', title: '网络开小差~' }); reject(new Error('network error')); }, }); });
|
使用示例:
1 2 3 4
| import { http } from '@/utils/http';
type Banner = { id: number; img: string }; const getBanner = () => http<Banner[]>({ url: '/home/banner' });
|
五、微信小程序热更新方案
很多开发者只会在 onLaunch 里 getUpdateManager,但以下场景依旧漏掉:
- 用户 24h 内未冷启动
- 开发版/体验版需要强制更新
封装 useWxUpdate,支持「间隔控制 + 强制弹窗 + 生命周期回调」。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| export function useWxUpdate(config?: UpdateConfig) { const merge = { ...DEFAULT_CONFIG, ...config }; const shouldCheck = () => { const last = uni.getStorageSync('last_update_check'); return !last || Date.now() - last > (merge.checkInterval || 86400) * 1000; }; const checkUpdate = () => { const mgr = wx.getUpdateManager(); mgr.onCheckForUpdate(({ hasUpdate }) => { uni.setStorageSync('last_update_check', Date.now()); merge.onAfterCheck?.(hasUpdate); }); mgr.onUpdateReady(() => { wx.showModal({ title: '更新提示', content: merge.customReadyContent!, showCancel: !merge.forceUpdate, success: (res) => res.confirm && mgr.applyUpdate(), }); }); }; return { checkUpdate, shouldCheck }; }
|
在 App.vue 调用:
1 2 3 4 5 6
| onLaunch(() => { const { checkUpdate, shouldCheck } = useWxUpdate({ forceUpdate: false }); if (shouldCheck()) checkUpdate(); });
|
六、Pinia 持久化存储(小程序适配)
安装:
1
| yarn add pinia pinia-plugin-persistedstate
|
main.ts 注入:
1 2 3 4 5 6 7 8 9 10
| import { createSSRApp } from 'vue'; import { createPinia } from 'pinia'; import persistedstate from 'pinia-plugin-persistedstate'; import App from './App.vue';
export function createApp() { const app = createSSRApp(App); const pinia = createPinia().use(persistedstate); return { app, pinia }; }
|
Store 示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| export const useUserStore = defineStore( 'user', () => { const token = ref(''); const setToken = (t: string) => (token.value = t); return { token, setToken }; }, { persist: { key: 'user', storage: { getItem: (key) => uni.getStorageSync(key), setItem: (key, value) => uni.setStorageSync(key, value), removeItem: (key) => uni.removeStorageSync(key), }, }, } );
|
七、Scss 废弃 API 警告消除
vite.config.ts 追加:
1 2 3 4 5 6 7 8 9 10
| export default defineConfig({ css: { preprocessorOptions: { scss: { api: 'modern-compiler', silenceDeprecations: ['legacy-js-api'], }, }, }, });
|
八、UI 组件库怎么选?
| 库 |
优点 |
缺点 |
| @dcloudio/uni-ui |
官方维护、零样式污染、easycom 自动引入 |
样式朴素 |
| uview-plus |
组件丰富、主题色生成器 |
文档需科学上网、广告多、issue 响应慢 |
⚠️ 无论选哪个,一定 看 npm 是否有源;很多插件市场包只提供 HBuilderX 安装,CI 无法自动构建。
九、常见踩坑 Top3
- 锁版本
@dcloudio/* 全部锁死,升级 Vue 到 3.5 也不会带来新特性,反而破坏编译器。
- easycom 不生效
把 pages.json 丢到 src/ 下,重新 dev。
- 小程序插件提示「未添加依赖」
在 manifest.json →「小程序插件配置」手动声明插件 ID。
十、一键运行
1 2 3 4 5 6 7 8
| yarn dev:mp-weixin
yarn dev:h5
yarn dev:app
|
十一、总结
CLI + Vscode 是真香,但模板只是起点。
把「请求-更新-存储-UI」四条链路封装完,后续业务直接撸页面即可。
文中所有代码已在 Gitee 开源。
👉 项目地址(顺手点个 Star):
https://gitee.com/sk20020228/uni-preset-vue3-ts