一、为什么要用 CLI 而不是 HBuilderX?
| 维度 | HBuilderX | CLI + Vscode |
|---|---|---|
| TS 类型推导 | ❌ 经常报红 | ✅ 丝滑 |
| 依赖管理 | 内置、黑盒 | 可见、可锁版本 |
| 工程化扩展 | 受限 | 随便玩 Vite 插件 |
| 团队协作 | 需要统一 IDE | 任意编辑器 |
⚠️ 用 HBuilderX 创建后再拖到 Vscode,90% 会遭遇「找不到模块」爆红,CLI 模板一步到位。
二、极速创建项目
bash
# 官方 vite-ts 模板(已集成 vue3.4 + ts5)
npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project
cd my-vue3-project
# 推荐用 yarn,npm 偶尔出现 peer 冲突
yarn
# 如果 ts 报错,先把 @vue/tsconfig 锁 0.4.0,再 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
typescript
// src/utils/http.ts
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'));
},
});
});
使用示例:
typescript
import { http } from '@/utils/http';
type Banner = { id: number; img: string };
const getBanner = () => http<Banner[]>({ url: '/home/banner' });
五、微信小程序热更新方案
很多开发者只会在 onLaunch 里 getUpdateManager,但以下场景依旧漏掉:
- 用户 24h 内未冷启动
- 开发版/体验版需要强制更新
封装 useWxUpdate,支持「间隔控制 + 强制弹窗 + 生命周期回调」。
javascript
// src/utils/update.ts
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 = () => {
// #ifdef MP-WEIXIN
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(),
});
});
// #endif
};
return { checkUpdate, shouldCheck };
}
在 App.vue 调用:
scss
onLaunch(() => {
// #ifdef MP-WEIXIN
const { checkUpdate, shouldCheck } = useWxUpdate({ forceUpdate: false });
if (shouldCheck()) checkUpdate();
// #endif
});
六、Pinia 持久化存储(小程序适配)
安装:
csharp
yarn add pinia pinia-plugin-persistedstate
main.ts 注入:
javascript
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 示例:
typescript
// src/stores/user.ts
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 追加:
php
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。
十、一键运行
bash
# 微信小程序
yarn dev:mp-weixin
# H5
yarn dev:h5
# App
yarn dev:app
十一、总结
CLI + Vscode 是真香,但模板只是起点。把「请求-更新-存储-UI」四条链路封装完,后续业务直接撸页面即可。文中所有代码已在 Gitee 开源。
👉 项目地址:gitee.com/sk20020228/...