万字图文实战:从0到1构建 UniApp + Vue3 + TypeScript 移动端跨平台开源脚手架
🚀 作者主页: 有来技术
🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot 🍃 vue-uniapp-template
🌺 仓库主页: Gitee 💫 Github 💫 GitCode
💖 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请纠正!
开局一张图,先看一下初期登录的效果图,内容和UI正在升级中…
目录
- 前言
- 环境准备
- 安装 Node
- 安装 VSCode
- 安装 vue-cli
- 创建项目
- 初始化项目
- 配置编译器
- 启动项目
- 代码规范配置
- 集成 ESLint
- 安装插件
- 配置 ESLint
- 添加 ESLint 脚本
- 测试效果
- 推荐配置
- 集成 Prettier
- 安装插件
- 安装依赖
- 配置 Prettier
- 配置忽略文件
- 添加格式化脚本
- 保存自动格式化
- 测试
- 集成 Stylelint
- 安装插件
- 安装依赖
- 配置 Stylelint
- 配置忽略文件
- 添加 Stylelint 脚本
- 保存自动修复
- 测试
- Git提交规范配置
- 集成 Husky
- 安装依赖
- 初始化
- 测试
- 集成 lint-staged
- 安装依赖
- 配置 lint-staged
- 添加 Husky 钩子
- 测试
- 集成 Commitlint
- 安装依赖
- 配置 Commitlint
- 添加 Husky 钩子
- 测试
- 集成 Commitizen 和 cz-git
- 安装依赖
- 配置 cz-git
- 添加 cz-git 脚本
- 测试
- 整合 Sass
- 整合 UnoCSS
- 安装插件
- 安装依赖
- 配置 UnoCSS
- 测试
- 添加 TabBar
- 添加页面
- 添加图标
- 配置 TabBar
- 测试
- 按需自动导入
- 安装依赖
- 配置自动导入
- 配置 ESLint 规则
- 测试
- 环境变量
- 配置环境变量
- 智能提示
- 整合 HTTP 请求
- 封装请求工具
- 登录接口定义
- 登录页面
- 登录测试
- 整合源码
- 整合 Pinia
- 安装依赖
- 全局注册
- 用户信息接口
- 用户状态管理
- 个人中心页面
- 测试效果
- 整合源码
- 反向代理
- 环境变量配置
- 请求工具的调整
- Vite 反向代理配置
- 测试与验证
- 整合源码
- 整合 wot-design-uni
- 安装依赖
- 配置自动引入组件
- Volar 支持
- 测试组件
- 整合源码
- 项目部署
- H5 部署
- 小程序发布
- 下载工具
- 获取小程序 AppID
- 配置项目
- 设置微信开发者工具
- 运行项目
- 上传发布
- 查看效果
- 结语
- 附:项目源码
前言
本文旨在从零开始,通过 vue-cli 构建一个基于 Vue3 和 TypeScript 的 UniApp 跨移动端开源脚手架模板。通过详实的步骤讲解,从环境配置到项目部署,全面涵盖开发中的各个重要环节,致力于打造高效的开发工具,提升项目质量和开发效率。
环境准备
vue-uniapp-template 是一个通过 vue-cli
构建的跨移动端脚手架模板,结合了 uniapp
、vue3
和 typescript
主流技术栈。在开始之前,需要准备以下环境。如果环境准备OK,请忽略本节。
安装 Node
Node.js
是运行 JavaScript 代码的环境,也是npm
包管理器的依赖。
打开 Node.js 官方下载页面,根据你的操作系统选择合适的版本进行下载,推荐安装 LTS 版本,这是长期支持版本,适合开发环境,比如这里选择 v20.18.0(LTS)
版本。
下载之后,双击安装包根据提示安装,通过以下命令检查是否成功安装:
node -v
安装 VSCode
VSCode
是一款非常流行的代码编辑器,特别适合前端开发。
访问 Visual Studio Code 官方网站 ,根据你的操作系统下载相应版本的 VSCode
,下载完成后,双击安装程序并按照提示完成安装。
安装 vue-cli
Vue CLI
是 Vue.js 的命令行工具,能够快速创建、开发、构建 Vue.js 项目。
打开终端或命令提示符, 使用 npm
全局安装 Vue CLI
:
npm install -g @vue/cli
安装完成后,检查 Vue CLI
是否安装成功:
vue --version
创建项目
初始化项目
按照 uni-app 官方文档 的步骤,通过 vue-cli
创建 uni-app
+ vue
+ typescript
脚手架:
npx degit dcloudio/uni-preset-vue#vite-ts vue-uniapp-template
如果使用命令创建失败,可以通过 Gitee 下载 ZIP 包:vite-ts 分支。
配置编译器
默认生成的 TypeScript
编译器配置文件 tsconfig.json
中继承的 @vue/tsconfig/tsconfig.json
文件不存在。因此,你需要移除此继承配置并添加相应的编译设置。
根据 TypeScript 官方配置文档,调整后的完整配置如下:
{"compilerOptions": {"module": "esnext","moduleResolution": "node","target": "esnext","allowJs": true,"skipLibCheck": true,"strict": true,"sourceMap": true,"baseUrl": ".","paths": {"@/*": ["./src/*"]},"lib": ["esnext", "dom"],"types": ["@dcloudio/types"]},"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],"exclude": ["node_modules", "dist"]
}
"module": "esnext"
: 指定模块系统为ESNext
,即最新的 ECMAScript 模块系统,支持import.meta
和其他最新的特性。"moduleResolution": "node"
: 模块解析策略,通常设置为Node
以支持 Node.js 风格的模块解析。"target": "esnext"
: 将目标 JavaScript 版本设置为ESNext
,编译输出现代浏览器能够支持的最新特性代码。"allowJs": true
: 允许 TypeScript 编译器处理.js
文件,混合使用 TypeScript 和 JavaScript 文件。"skipLibCheck": true
: 跳过库文件的类型检查,提升编译速度。"strict": true
: 启用所有严格类型检查选项。
启动项目
创建完成后,使用 VSCode
打开项目并启动:
# 安装依赖
pnpm install
# 启动项目
pnpm run dev:h5
项目启动后,访问 http://localhost:5173 预览效果:
代码规范配置
为了保证项目代码的规范性和一致性,可以为项目配置 ESLint
、Stylelint
、Prettier
以及 Husky
,从而确保代码质量和开发流程的一致性。
集成 ESLint
ESLint
是一款 JavaScript 和 TypeScript 的代码规范工具,能够帮助开发团队保持代码风格一致并减少常见错误。
ESLint 中文网:https://eslint.nodejs.cn/
安装插件
VSCode 插件市场搜索 ESLint 插件并安装
配置 ESLint
通过以下命令快速生成 ESLint 配置文件:
npx eslint --init
执行该命令后,ESLint 会通过交互式问题的方式,帮助生成配置文件。针对 9.x 版本,默认会生成基于 Flat Config 格式的 eslint.config.mjs
文件,与之前的 .eslintrc
格式有所不同。
默认生成的 eslint.config.mjs
文件如下所示:
在此基础上,可以根据项目的需求进行一些定制化配置,例如添加忽略规则或自定义的特殊规则。
import globals from "globals"; // 全局变量配置
import pluginJs from "@eslint/js"; // JavaScript 的推荐配置
import tseslint from "typescript-eslint"; // TypeScript 配置
import pluginVue from "eslint-plugin-vue"; // Vue 配置export default [{files: ["**/*.{js,mjs,cjs,ts,vue}"]}, // 校验的文件类型{languageOptions: { globals: {...globals.browser , ...globals.node} }}, // 浏览器/Node环境全局变量pluginJs.configs.recommended, // JavaScript 推荐配置...tseslint.configs.recommended, // TypeScript 推荐配置...pluginVue.configs["flat/essential"], // Vue 推荐配置{ files: ["**/*.vue"], languageOptions: { parserOptions: { parser: tseslint.parser } } }, // 对 .vue 文件使用 TypeScript 解析器// 添加忽略的文件或目录{ignores: ["/dist","/public","/node_modules","**/*.min.js","**/*.config.mjs","**/*.tsbuildinfo","/src/manifest.json",]},// 自定义规则{rules: {quotes: ["error", "double"], // 强制使用双引号"quote-props": ["error", "always"], // 强制对象的属性名使用引号semi: ["error", "always"], // 要求使用分号indent: ["error", 2], // 使用两个空格进行缩进"no-multiple-empty-lines": ["error", { max: 1 }], // 不允许多个空行"no-trailing-spaces": "error", // 不允许行尾有空格// TypeScript 规则"@typescript-eslint/no-explicit-any": "off", // 禁用 no-explicit-any 规则,允许使用 any 类型"@typescript-eslint/explicit-function-return-type": "off", // 不强制要求函数必须明确返回类型"@typescript-eslint/no-empty-interface": "off", // 禁用 no-empty-interface 规则,允许空接口声明"@typescript-eslint/no-empty-object-type": "off", // 允许空对象类型// Vue 规则"vue/multi-word-component-names": "off", // 关闭多单词组件名称的限制"vue/html-indent": ["error", 2], // Vue 模板中的 HTML 缩进使用两个空格"vue/no-v-html": "off", // 允许使用 v-html (根据实际项目需要)},},
];
添加 ESLint 脚本
为了方便使用 ESLint,可以在 package.json
中添加 lint
脚本命令:
{"scripts": {"lint:eslint": "eslint --fix ./src"}
}
此脚本会自动修复符合 ESLint 规则的代码问题,并输出检查结果。
测试效果
在 App.vue
文件中声明一个未使用的变量,并运行 pnpm run lint:eslint
,可以看到 ESLint 提示该变量未使用。如下图所示:
推荐配置
安装 Vue 文件解析器 vue-eslint-parser
:
pnpm add -D vue-eslint-parser
针对不同文件配置插件和解析器:
// eslint.config.mjs
import globals from "globals";
import js from "@eslint/js";// ESLint 核心插件
import pluginVue from "eslint-plugin-vue";
import pluginTypeScript from "@typescript-eslint/eslint-plugin";// Prettier 插件及配置
import configPrettier from "eslint-config-prettier";
import pluginPrettier from "eslint-plugin-prettier";// 解析器
import * as parserVue from "vue-eslint-parser";
import * as parserTypeScript from "@typescript-eslint/parser";// 定义 ESLint 配置
export default [// 通用 JavaScript/TypeScript 配置{...js.configs.recommended,ignores: ["/dist","/public","/node_modules","**/*.min.js","**/*.config.mjs","**/*.tsbuildinfo","/src/manifest.json",],languageOptions: {globals: {...globals.browser, // 浏览器变量 (window, document 等)...globals.node, // Node.js 变量 (process, require 等)},},plugins: {prettier: pluginPrettier,},rules: {...configPrettier.rules,...pluginPrettier.configs.recommended.rules,"no-debug": "off", // 允许使用 debugger"prettier/prettier": ["error",{endOfLine: "auto", // 解决换行符冲突},],},},// TypeScript 配置{files: ["**/*.?([cm])ts"],languageOptions: {parser: parserTypeScript,parserOptions: {sourceType: "module",},},plugins: {"@typescript-eslint": pluginTypeScript,},rules: {...pluginTypeScript.configs.recommended.rules,"@typescript-eslint/no-explicit-any": "off", // 允许使用 any"@typescript-eslint/no-empty-function": "off", // 允许空函数"@typescript-eslint/no-empty-object-type": "off", // 允许空对象类型"@typescript-eslint/consistent-type-imports": ["error",{ disallowTypeAnnotations: false, fixStyle: "inline-type-imports" },], // 统一类型导入风格},},// TypeScript 声明文件的特殊配置{files: ["**/*.d.ts"],rules: {"eslint-comments/no-unlimited-disable": "off", // 关闭 eslint 注释相关规则"unused-imports/no-unused-vars": "off", // 忽略未使用的导入},},// JavaScript (commonjs) 配置{files: ["**/*.?([cm])js"],rules: {"@typescript-eslint/no-var-requires": "off", // 允许 require},},// Vue 文件配置{files: ["**/*.vue"],languageOptions: {parser: parserVue,parserOptions: {parser: "@typescript-eslint/parser",sourceType: "module",},},plugins: {vue: pluginVue,},processor: pluginVue.processors[".vue"],rules: {...pluginVue.configs["vue3-recommended"].rules,"vue/no-v-html": "off", // 允许 v-html"vue/require-default-prop": "off", // 允许没有默认值的 prop"vue/multi-word-component-names": "off", // 关闭组件名称多词要求"vue/html-self-closing": ["error",{html: { void: "always", normal: "always", component: "always" },svg: "always",math: "always",},], // 自闭合标签},},
];
集成 Prettier
Prettier 是一个代码格式化工具,能够和 ESLint 配合使用,确保代码风格统一。
prettier 中文网:https://prettier.nodejs.cn/
安装插件
VSCode 插件市场搜索 Prettier - Code formatter
插件安装
安装依赖
pnpm install -D prettier eslint-config-prettier eslint-plugin-prettier
-
prettier:主要的 Prettier 格式化库。
-
eslint-plugin-prettier:将 Prettier 的规则作为 ESLint 的规则来运行。
-
eslint-config-prettier:禁用所有与格式相关的 ESLint 规则,以避免和 Prettier 的冲突。
配置 Prettier
项目根目录下新建配置文件 prettier.config.mjs
,添加常用规则:
export default {printWidth: 100, // 每行最多字符数量,超出换行(默认80)tabWidth: 2, // 缩进空格数,默认2个空格useTabs: false, // 指定缩进方式,空格或tab,默认false,即使用空格semi: true, // 使用分号singleQuote: false, // 使用单引号 (true:单引号;false:双引号)trailingComma: 'all', // 末尾使用逗号
};
配置忽略文件
项目根目录新建 .prettierignore
文件指定 Prettier 不需要格式化的文件和文件夹
# .prettierignore
node_modules
dist
public
*.min.js
添加格式化脚本
在 package.json
文件中添加:
{"scripts": {"format": "prettier --write ./src"}
}
保存自动格式化
打开 VSCode 的 File
→ Preferences
→ Settings
,然后选择 Open Settings (JSON)
,添加以下配置
{"editor.formatOnSave": true, // 保存格式化文件"editor.defaultFormatter": "esbenp.prettier-vscode" // 指定 prettier 为所有文件默认格式化器
}
测试
下图演示了保存时的自动格式化效果,展示了代码中引号和换行的自动调整:
集成 Stylelint
Stylelint 一个强大的 CSS linter(检查器),可帮助您避免错误并强制执行约定。
Stylelint 官网:https://stylelint.io/
安装插件
VSCode 插件搜索 Stylelint
并安装
安装依赖
pnpm install -D postcss postcss-html postcss-scss stylelint stylelint-config-recommended stylelint-config-recommended-scss stylelint-config-recommended-vue stylelint-config-recess-order stylelint-config-html stylelint-prettier
依赖 | 说明 | 备注 |
---|---|---|
postcss | CSS 解析工具,允许使用现代 CSS 语法并将其转换为兼容的旧语法 | - |
postcss-html | 解析 HTML (类似 HTML) 的 PostCSS 语法 | 参见 postcss-html 文档 |
postcss-scss | PostCSS 的 SCSS 解析器 | 参见 postcss-scss 文档,支持 CSS 行类注释 |
stylelint | stylelint 核心库 | 参见 stylelint |
stylelint-config-recommended | 提供了基础的 Stylelint 配置,适用于大多数项目,允许自定义规则集 | 与 stylelint-config-standard 相比,此配置提供了更多的灵活性 |
stylelint-config-recommended-scss | 扩展基础配置,为 SCSS 特定规则提供支持 | 参见 stylelint-config-recommended-scss 文档 |
stylelint-config-recommended-vue | 扩展基础配置,为 Vue 文件中的样式提供支持 | 参见 stylelint-config-recommended-vue 文档 |
stylelint-config-recess-order | 提供优化样式顺序的配置 | 参见 CSS 书写顺序规范 |
stylelint-config-html | 为 HTML (类似 HTML) 文件提供共享配置 | 参见 stylelint-config-html 文档 |
stylelint-prettier | 集成 stylelint 和 prettier,确保样式同时满足两个工具的规范 | - |
其中选择 stylelint-config-recommended 替代 stylelint-config-standard 的原因在于它不仅提供了灵活性,还更加轻量。stylelint-config-recommended 默认包含的规则较少,避免了 stylelint-config-standard 中可能不需要的规则,这样可以减少配置的复杂度,提高项目的启动速度,同时让开发者能够集中关注对项目真正重要的风格指南。轻量配置有助于简化工作流程,特别是在大型或复杂的项目中。
配置 Stylelint
根目录新建 .stylelintrc.cjs
文件,配置如下:
{"extends": ["stylelint-config-recommended","stylelint-config-recommended-scss","stylelint-config-recommended-vue/scss","stylelint-config-html/vue","stylelint-config-recess-order"],"plugins": ["stylelint-prettier"],"overrides": [{"files": ["**/*.{vue,html}"],"customSyntax": "postcss-html"},{"files": ["**/*.{css,scss}"],"customSyntax": "postcss-scss"}],"rules": {"import-notation": "string","selector-class-pattern": null,"custom-property-pattern": null,"keyframes-name-pattern": null,"no-descending-specificity": null,"no-empty-source": null,"selector-pseudo-class-no-unknown": [true,{"ignorePseudoClasses": ["global", "export", "deep"]}],"unit-no-unknown": [true, {"ignoreUnits": ["rpx"]}] "property-no-unknown": [true,{"ignoreProperties": []}],"at-rule-no-unknown": [true,{"ignoreAtRules": ["apply", "use", "forward"]}]}
}
配置忽略文件
根目录创建 .stylelintignore 文件,配置忽略文件如下:
*.min.js
dist
public
node_modules
添加 Stylelint 脚本
package.json 添加 Stylelint 检测指令:
"scripts": {"lint:stylelint": "stylelint \"**/*.{css,scss,vue,html}\" --fix"}
保存自动修复
项目根目录下.vscode/settings.json
文件添加配置:
{"editor.codeActionsOnSave": {"source.fixAll.stylelint": true },"stylelint.validate": ["css", "scss", "vue", "html"]
}
为了验证把尺寸属性 width 放置在定位属性 position 前面,根据 CSS 书写顺序规范 推断是不符合规范的,在保存时 Stylelint 自动将属性重新排序,达到预期。
测试
执行以下命令进行检测
npm run lint:stylelint
Git提交规范配置
配置 Husky 的 pre-commit
和 commit-msg
钩子,实现代码提交的自动化检查和规范化。
- pre-commit: 使用 Husky + Lint-staged,在提交前进行代码规范检测和格式化。确保项目已配置 ESLint、Prettier 和 Stylelint。
- commit-msg: 结合 Husky、Commitlint、Commitizen 和 cz-git,生成规范化且自定义的 Git commit 信息。
集成 Husky
Husky 是 Git 钩子工具,可以设置在 git 各个阶段(pre-commit
、commit-msg
等)触发。
Husky官网:https://typicode.github.io
安装依赖
pnpm add -D husky
初始化
init
命令简化了项目中的 husky 设置。它会在 .husky/
中创建 pre-commit
脚本,并更新 package.json
中的 prepare
脚本。
pnpm exec husky init
测试
通过 pre-commit
钩子,可以自动运行各种代码检查工具,在提交代码前强制执行代码质量和样式检查。常见的工具包括:
eslint
:用于检查和修复 JavaScript/TypeScript 代码中的问题。stylelint
:用于检测和修复 CSS/SCSS 样式问题。
接下来,集成 lint-staged
和 commitlint
来进一步完善开发体验。
集成 lint-staged
lint-staged
是一个工具,专门用于只对 Git 暂存区的文件运行 lint 或其他任务,确保只检查和修复被修改或新增的代码部分,而不会影响整个代码库。这样可以显著提升效率,尤其是对于大型项目。
安装依赖
使用以下命令安装 lint-staged
:
pnpm add -D lint-staged
配置 lint-staged
在 package.json
中添加 lint-staged
配置,确保在 pre-commit
阶段自动检测暂存的文件:
{"name": "vue-uniapp-template","version": "0.0.0","lint-staged": {"*.{js,ts}": ["eslint --fix","prettier --write"],"*.{cjs,json}": ["prettier --write"],"*.{vue,html}": ["eslint --fix","prettier --write","stylelint --fix"],"*.{scss,css}": ["stylelint --fix","prettier --write"],"*.md": ["prettier --write"]}
}
在 package.json
的 scripts
部分中,添加用于运行 lint-staged
的命令:
"scripts": {"lint:lint-staged": "lint-staged"
}
添加 Husky 钩子
在项目根目录的 .husky/pre-commit
中添加以下命令,确保在提交代码前执行 lint-staged
:
pnpm run lint:lint-staged
测试
提交代码时,lint-staged
会自动对暂存的文件运行相应的 lint 任务。
通过这种集成方式,确保代码在提交前经过自动格式化和校验,提高代码质量和一致性。
集成 Commitlint
commitlint
用于检查 Git 提交信息是否符合特定规范(如 Angular 提交规范),从而保证提交信息的一致性。
Commitlint官网:https://commitlint.js.org/
安装依赖
pnpm add -D @commitlint/cli @commitlint/config-conventional
配置 Commitlint
在项目根目录下创建 commitlint.config.cjs
文件,添加以下内容来启用 Angular 规范:
module.exports = {// 继承的规则extends: ["@commitlint/config-conventional"],// 自定义规则rules: {// 提交类型枚举,git提交type必须是以下类型 @see https://commitlint.js.org/#/reference-rules"type-enum": [2,"always",["feat", // 新增功能"fix", // 修复缺陷"docs", // 文档变更"style", // 代码格式(不影响功能,例如空格、分号等格式修正)"refactor", // 代码重构(不包括 bug 修复、功能新增)"perf", // 性能优化"test", // 添加疏漏测试或已有测试改动"build", // 构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)"ci", // 修改 CI 配置、脚本"revert", // 回滚 commit"chore", // 对构建过程或辅助工具和库的更改(不影响源文件、测试用例)],],"subject-case": [0], // subject大小写不做校验},
};
添加 Husky 钩子
将 commitlint
与 Husky 集成,在 .husky/commit-msg
文件中添加以下内容,确保提交信息符合规范:
npx --no-install commitlint --edit $1
测试
根据 Angular 的提交规范,提交信息由以下部分组成:
- 类型:表示本次提交的类型,例如
feat
(新功能)、fix
(修复 bug)、docs
(文档更新)。 - 作用域(可选):说明本次提交影响的模块,例如
auth
、ui
。 - 简短描述:简洁明了的提交描述,限定在 50 字符以内。
当你尝试提交不符合规范的提交信息时,提交会被阻止,并显示相关错误提示。如下图所示:
集成 Commitizen 和 cz-git
-
commitizen: 是一个帮助开发者以标准化格式生成提交信息的工具。–Commitizen 官方文档
-
cz-git:
cz-git
是Commitizen
的适配器之一,它基于Commitizen
,提供了更多自定义功能和增强的交互体验。–cz-git 官方文档
安装依赖
pnpm add -D commitizen cz-git
配置 cz-git
在项目中初始化 Commitizen
,并配置使用 cz-git
作为适配器。在 package.json
中添加以下配置:
"config": {"commitizen": {"path": "node_modules/cz-git"}
}
在commitlint
的配置文件 commitlint.config.cjs
中添加配置,commitlint 配置模板:https://cz-git.qbb.sh/zh/config/
module.exports = {// 继承的规则extends: ["@commitlint/config-conventional"],// 自定义规则rules: {// ...},// cz-git 配置prompt: {messages: {type: "选择你要提交的类型 :",scope: "选择一个提交范围(可选):",customScope: "请输入自定义的提交范围 :",subject: "填写简短精炼的变更描述 :\n",body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n',breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n',footerPrefixesSelect: "选择关联issue前缀(可选):",customFooterPrefix: "输入自定义issue前缀 :",footer: "列举关联issue (可选) 例如: #31, #I3244 :\n",generatingByAI: "正在通过 AI 生成你的提交简短描述...",generatedSelectByAI: "选择一个 AI 生成的简短描述:",confirmCommit: "是否提交或修改commit ?",},// prettier-ignoretypes: [{ value: "feat", name: "特性: ✨ 新增功能", emoji: ":sparkles:" },{ value: "fix", name: "修复: 🐛 修复缺陷", emoji: ":bug:" },{ value: "docs", name: "文档: 📝 文档变更", emoji: ":memo:" },{ value: "style", name: "格式: 💄 代码格式(不影响功能,例如空格、分号等格式修正)", emoji: ":lipstick:" },{ value: "refactor", name: "重构: ♻️ 代码重构(不包括 bug 修复、功能新增)", emoji: ":recycle:" },{ value: "perf", name: "性能: ⚡️ 性能优化", emoji: ":zap:" },{ value: "test", name: "测试: ✅ 添加疏漏测试或已有测试改动", emoji: ":white_check_mark:"},{ value: "build", name: "构建: 📦️ 构建流程、外部依赖变更(如升级 npm 包、修改 vite 配置等)", emoji: ":package:"},{ value: "ci", name: "集成: 🎡 修改 CI 配置、脚本", emoji: ":ferris_wheel:"},{ value: "revert", name: "回退: ⏪️ 回滚 commit",emoji: ":rewind:"},{ value: "chore", name: "其他: 🔨 对构建过程或辅助工具和库的更改(不影响源文件、测试用例)", emoji: ":hammer:"},],useEmoji: true,emojiAlign: "center",useAI: false,aiNumber: 1,themeColorCode: "",scopes: [],allowCustomScopes: true,allowEmptyScopes: true,customScopesAlign: "bottom",customScopesAlias: "custom",emptyScopesAlias: "empty",upperCaseSubject: false,markBreakingChangeMode: false,allowBreakingChanges: ["feat", "fix"],breaklineNumber: 100,breaklineChar: "|",skipQuestions: [],issuePrefixes: [{ value: "closed", name: "closed: ISSUES has been processed" }],customIssuePrefixAlign: "top",emptyIssuePrefixAlias: "skip",customIssuePrefixAlias: "custom",allowCustomIssuePrefix: true,allowEmptyIssuePrefix: true,confirmColorize: true,maxHeaderLength: Infinity,maxSubjectLength: Infinity,minSubjectLength: 0,scopeOverrides: undefined,defaultBody: "",defaultIssues: "",defaultScope: "",defaultSubject: "",},
};
添加 cz-git 脚本
在package.json
文件中添加 commit
脚本命令
"scripts": {"commit": "git-cz"}
测试
执行 pnpm run commit
命令后,按照提示输入相关信息,最终生成符合规范的提交信息。
整合 Sass
Sass是帮助开发者编写、管理和维护样式的强大工具,通过 <style lang="scss">
使用。它提供变量、嵌套、混合等功能,提升了样式的可维护性和开发效率,尤其在复杂项目中减少重复代码、提高复用性。
pnpm add -D sass sass-loader
整合 UnoCSS
UnoCSS 是一个高性能、灵活且按需生成的原子化 CSS 引擎。
官方网站:https://unocss.net/
先比较下
内部样式 | UnoCSS原子样式 |
---|---|
![]() | ![]() |
安装插件
VSCode
安装 UnoCSS
插件
安装依赖
本次整合基于官网提供的社区预设 unocss-preset-weapp。该预设内置了 transformer
,用于解决小程序的兼容性问题。
进一步参考 unocss-preset-weapp 的 uniapp_vue3 使用与配置指南,使用以下命令安装 UnoCSS 和 unocss-preset-weapp
:
pnpm add -D unocss unocss-preset-weapp
配置 UnoCSS
参考 unocss-preset-weapp 的 uniapp_vue3 使用与配置指南,配置如下:
-
vite.config.ts
在
vite.config.ts
中添加如下配置,整合 UnoCSS 到 UniApp 项目:import { defineConfig } from 'vite' import uni from '@dcloudio/vite-plugin-uni'export default defineConfig(async () => {const UnoCss = await import('unocss/vite').then(i => i.default)return {plugins: [uni(),// 配置 UnoCSSUnoCss(),],} })
-
unocss.config.ts
添加unocss.config.ts文件,搭配 unocss vscode 插件,智能提示
import presetWeapp from "unocss-preset-weapp"; import { extractorAttributify, transformerClass } from "unocss-preset-weapp/transformer";const { presetWeappAttributify, transformerAttributify } = extractorAttributify();export default {presets: [// https://github.com/MellowCo/unocss-preset-weapppresetWeapp(),// attributify autocompletepresetWeappAttributify(),],shortcuts: [{"flex-center": "flex justify-center items-center","flex-col": "flex flex-col",},],transformers: [// https://github.com/MellowCo/unocss-preset-weapp/tree/main/src/transformer/transformerAttributifytransformerAttributify(),// https://github.com/MellowCo/unocss-preset-weapp/tree/main/src/transformer/transformerClasstransformerClass(),], };
shortcuts
自定义样式组合:可以在 shortcuts
中定义常用的样式组合,以便简化项目中的样式使用和维护,避免冗余和重复的样式。
-
main.ts
import 'uno.css'
测试
下图展示了在 VSCode 中测试 UnoCSS 时,智能提示和样式设置功能已经正常生效。
此外,在 unocss.config.ts
文件中预设的 shortcuts
组合样式也得到了正确应用。
添加 TabBar
在 APP 开发中,底部导航栏(TabBar)是移动端应用的重要部分,方便用户在不同页面间进行切换。
添加页面
在初始化的模板项目中,src/pages
目录下默认有一个 index/index.vue
页面。为了更好地演示 TabBar
的切换效果,我们在 pages
目录下再新增两个页面:
-
工作台页面(
src/pages/work/index.vue
):<template><view class="flex-center flex-col"><view><text class="text-cyan font-bold text-lg">工作台</text></view></view> </template>
-
我的页面(
src/pages/my/index.vue
):<template><view class="flex-center flex-col"><view><text class="text-blue font-bold text-lg">我的</text></view></view> </template>
添加图标
在 src/static
目录下创建一个 tabbar
文件夹,存放从 iconfont 获取的图标。每个图标都需要有未激活和激活两种状态的样式。
配置 TabBar
在 UniApp 项目中,底部导航栏(TabBar)通过配置 pages.json
文件来实现。首先,找到并打开项目根目录下的 src/pages.json
文件。在该文件中,可以为每个页面配置导航栏,同时定义 TabBar。
下面是完整的配置示例,注意 tabBar
中的 pagePath
必须对应 pages
目录下的实际页面路径。
{"pages": [{"path": "pages/index/index","style": {"navigationBarTitleText": "首页"}},{"path": "pages/work/index","style": {"navigationBarTitleText": "工作台"}},{"path": "pages/mine/index","style": {"navigationBarTitleText": "我的"}}],"tabBar": {"color": "#474747","selectedColor": "#3B8DFF","backgroundColor": "#F8F8F8","list": [{"pagePath": "pages/index/index","text": "首页","iconPath": "static/tabbar/home.png","selectedIconPath": "static/tabbar/home-active.png"},{"pagePath": "pages/work/index","text": "工作台","iconPath": "static/tabbar/work.png","selectedIconPath": "static/tabbar/work-active.png"},{"pagePath": "pages/mine/index","text": "我的","iconPath": "static/tabbar/mine.png","selectedIconPath": "static/tabbar/mine-active.png"}]}
}
测试
按需自动导入
在传统的 Vue 开发中,我们通常需要在每个页面手动导入 Vue 组合式 API(如 ref
, reactive
, onMounted
等)。随着项目的增大,手动导入会增加代码的冗余度,降低开发体验。
通过对比,来看一下手动导入与按需自动导入的区别:
手动导入 | 按需自动导入 |
---|---|
![]() | ![]() |
手动导入: 每个页面都需要显式地引入 ref
, reactive
, onMounted
等组合式 API。
按需自动导入: 配置了自动导入插件后,这些 API 无需显式导入即可直接使用,减少了重复代码,提高了开发效率。
由于当前还未整合按需自动导入插件,所以右图的代码仍然报错,提示未找到 ref
和 reactive
的定义。这展示了按需自动导入的重要性:一旦整合插件,这类错误将被消除,代码更加简洁易维护。
安装依赖
首先使用以下命令安装 unplugin-auto-import
插件:
pnpm add -D unplugin-auto-import
配置自动导入
接着,在 vite.config.ts
中配置 unplugin-auto-import
插件,确保 Vue 和 UniApp 的 API 能够自动按需导入。
// vite.config.ts
import { defineConfig } from "vite";
import AutoImport from "unplugin-auto-import/vite";export default defineConfig(async () => {return {plugins: [uni(), // 这里是你的 uni-app 插件AutoImport({imports: ["vue", "uni-app"], // 自动导入 Vue 和 UniApp 的 APIdts: "src/types/auto-imports.d.ts", // 自动生成类型声明文件eslintrc: {enabled: true, // 生成 ESLint 配置文件filepath: './.eslintrc-auto-import.json', // ESLint 配置文件路径},}),],};
});
配置 ESLint 规则
为了让 ESLint 能识别这些通过 unplugin-auto-import
自动导入的 API,需要在 ESLint 的配置中引入 unplugin-auto-import
生成的 .eslintrc-auto-import.json
文件。
在 ESLint 9.x 版本中,使用 Flat Config 时不再支持 extends
关键字。因此,不能使用以下配置:
// 错误示例
export default [{extends: ["./.eslintrc-auto-import.json"], // 这种扩展方式在 Flat Config 中不再支持},
];
取而代之的是直接引入 .eslintrc-auto-import.json
文件内容,通过解析文件的方式将自动导入的全局变量配置整合进 ESLint 配置。
在 eslint.config.mjs
中添加如下配置:
// eslint.config.mjs 正确的配置
import { readFileSync } from "fs";
import { fileURLToPath } from "url";
import { dirname, resolve } from "path";// 动态读取 .eslintrc-auto-import.json 文件内容
const autoImportConfig = JSON.parse(readFileSync(resolve(dirname(fileURLToPath(import.meta.url)), ".eslintrc-auto-import.json"),"utf-8",),
);
export default [{// 语言选项配置,定义全局变量languageOptions: {globals: {// ......autoImportConfig.globals, // 自动导入的全局变量},},},
];
这样配置后,ESLint 将能够识别通过自动导入的 API,避免例如 'ref' is not defined
这样的错误,从而使项目的开发更加顺畅。
测试
通过上述步骤配置后,原先在未手动导入情况下报错的页面,现在可以正常使用 ref
, reactive
等 API,而无需显式导入。
以下是最终的效果:
整合按需自动导入后,你将不再需要在每个页面显式导入 Vue 或 UniApp 的组合式 API,大幅度减少了重复的代码,提升了开发体验。
环境变量
Vite 环境变量主要是为了区分开发、测试、生产等环境的变量
下面的整合过程参考 Vite 环境变量配置官方文档
配置环境变量
项目根目录新建 .env.development
、.env.production
-
开发环境变量配置:.env.development
# 变量必须以 VITE_ 为前缀才能暴露给外部读取# 项目运行的端口号 VITE_APP_PORT = 5173# API 基础路径,开发环境下的请求前缀 VITE_APP_BASE_API = '/dev-api'# API 服务器的 URL VITE_APP_API_URL = https://api.youlai.tech
-
生产环境变量配置:.env.production
# API 基础路径,生产环境下的请求前缀 VITE_APP_BASE_API = '/prod-api'# API 服务器的 URL VITE_APP_API_URL = https://api.youlai.tech
智能提示
首先,在 src/types/env.d.ts
文件中添加环境变量的类型声明:
// src/types/env.d.ts
interface ImportMetaEnv {/*** 应用端口*/VITE_APP_PORT: number;/*** API 基础路径*/VITE_APP_BASE_API: string;/*** API 服务器的 URL*/VITE_APP_API_URL: string;
}interface ImportMeta {readonly env: ImportMetaEnv;
}
确保 TypeScript 编译器使用的模块系统支持 import.meta
。在 tsconfig.json
文件中,你可以指定 es2020
、es2022
或 esnext
等模块系统。例如:
// tsconfig.json
{"compilerOptions": {"module": "esnext", // 支持 import.meta// ...}
}
在任意页面中测试 import.meta
是否能够智能提示环境变量:
console.log(import.meta.env.VITE_APP_PORT);
整合 HTTP 请求
通过一个登录案例演示如何在Uniapp中整合HTTP请求。这里未使用axios和alova请求库的原因在于,Uniapp自身提供了跨平台的uni.request方法,该方法在不同平台(如小程序、App和H5)下表现一致,且无需额外安装第三方库,从而减少了项目的依赖复杂性和体积。
封装请求工具
在 global.d.ts
中定义全局响应数据类型 ResponseData
:
// src/types/global.d.ts
declare global {/*** 响应数据结构*/interface ResponseData<T = any> {code: string; // 业务状态码data: T; // 返回数据msg: string; // 消息}
}
export {};
在 src/utils/request.ts
下创建一个 HTTP 请求工具,用于与 API 服务器进行通信:
// src/utils/request.ts
export default function request<T>(options: UniApp.RequestOptions): Promise<T> {const token = uni.getStorageSync("token"); // 从本地缓存获取 tokenreturn new Promise((resolve, reject) => {uni.request({...options,// VITE_APP_API_URL 是在 Vite 项目的 .env.development 文件中配置的环境变量,表示 API 的路径url: `${import.meta.env.VITE_APP_API_URL}${options.url}`,header: {...options.header,Authorization: token,},success: (response) => {const resData = response.data as ResponseData<T>;// 业务状态码 00000 表示成功if (resData.code === "00000") {resolve(resData.data);} else {uni.showToast({title: resData.msg || "业务处理失败",icon: "none",duration: 2000,});reject({message: resData.msg || "业务处理失败",code: resData.code,});}},fail: (error) => {uni.showToast({title: "网络请求失败",icon: "none",duration: 2000,});reject({message: "网络请求失败",error,});},});});
}
注意事项
当首次使用该请求工具类时,可能会出现 'uni' is not defined
的 ESLint 错误,如下图所示:
为解决此问题,需要在 ESLint 配置文件中定义 uni
为全局变量:
// eslint.config.mjs
export default [{// 语言选项配置,定义全局变量languageOptions: {globals: {// ......{uni: "readonly", // uni-app 全局对象},},},},
];
登录接口定义
请求URL: https://api.youlai.tech/api/v1/auth/login
请求参数:
参数名 | 参数值 |
---|---|
username | admin |
password | 123456 |
返回响应:
{"code": "00000","data": {"accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIxxx.xxxxxxx","tokenType": "Bearer"},"msg": "一切ok"
}
根据上述登录接口信息,创建 AuthAPI
类用于处理登录请求:
import request from "@/utils/request";const AuthAPI = {/*** 登录接口** @param username 用户名* @param password 密码* @returns 返回 token*/login(username: string, password: string): Promise<LoginResult> {return request<LoginResult>({url: "/api/v1/auth/login",method: "POST",data: {username,password,},header: {"Content-Type": "application/x-www-form-urlencoded",},});},/*** 登出接口*/logout(): Promise<void> {return request({url: "/api/v1/auth/logout",method: "DELETE",});},
};export default AuthAPI;/** 登录响应 */
export interface LoginResult {/** 访问token */accessToken?: string;/** token 类型 */tokenType?: string;
}
登录页面
新建 src/pages/login/index.vue
文件,编写登录页面及逻辑:
<template><view class="flex-col"><input v-model="username" placeholder="请输入用户名" /><input v-model="password" placeholder="请输入密码" type="password" /><button @click="handleLogin">登录</button></view>
</template><script lang="ts" setup>
import AuthAPI, { LoginResult } from '@/api/auth';const username = ref('');
const password = ref('');
const router = useRouter();const handleLogin = async () => {try {const response: LoginResult = await AuthAPI.login(username.value, password.value);if (response.accessToken) {uni.setStorageSync('token', response.accessToken);uni.showToast({ title: '登录成功', icon: 'success' });} else {uni.showToast({ title: '登录失败', icon: 'none' });}} catch (err) {uni.showToast({ title: '登录失败', icon: 'none' });}
};
</script><style scoped>
</style>
在 pages.json
文件中,声明登录页面的路由:
// src/pages.json
{"pages": [{"path": "pages/login/index","style": {"navigationBarTitleText": "登录"}}]
}
登录测试
访问登录页面:http://localhost:5173/#/pages/login/index,输入用户名和密码 (admin
/123456
) 测试登录接口,登录成功后可以看到返回的访问令牌。
整合源码
整合HTTP请求
代码版本:vue-uniapp-template#737f6a3。
整合 Pinia
Pinia 是 Vue 的状态管理库,专为跨组件或页面共享状态设计。
- Pinia 官方文档: https://pinia.vuejs.org/zh/getting-started.html
安装依赖
首先,安装 pinia
依赖:
pnpm add pinia
全局注册
在项目的 src
目录下创建 store
文件夹,并新建 index.ts
文件,初始化并注册 Pinia 实例。
// src/store/index.ts
import type { App } from "vue";
import { createPinia } from "pinia";const store = createPinia();
// 注册 Pinia
export function setupStore(app: App<Element>) {app.use(store); // 全局注册 Pinia
}
接着,将 store
在项目入口文件 main.ts
中引入,并将其作为全局插件传递给应用:
// src/main.ts
import { createSSRApp } from "vue";
import App from "./App.vue";import { setupStore } from "@/store";export function createApp() {const app = createSSRApp(App);// 全局注册 storesetupStore(app);return {app,};
}
接下来,我们通过 Pinia 管理登录状态和用户信息,并在多个页面共享状态。
用户信息接口
编写一个 API 来获取当前登录用户的信息:
import request from "@/utils/request";const USER_BASE_URL = "/api/v1/users";const UserAPI = {/*** 获取当前登录用户信息** @returns 登录用户昵称、头像信息,包括角色和权限*/getUserInfo(): Promise<UserInfo> {return request<UserInfo>({url: `${USER_BASE_URL}/me`,method: "GET",});},
};
export default UserAPI;/** 登录用户信息 */
export interface UserInfo {/** 用户ID */userId?: number;/** 用户名 */username?: string;/** 昵称 */nickname?: string;/** 头像URL */avatar?: string;/** 角色 */roles: string[];/** 权限 */perms: string[];
}
用户状态管理
通过 Pinia 定义 user
模块,管理登录状态、用户信息等。
// src/store/module/user.ts
import { defineStore } from "pinia";
import AuthAPI from "@/api/auth";
import UserAPI, { UserInfo } from "@/api/user";export const useUserStore = defineStore("user", () => {// 确保 token 是响应式的const token = ref<string>(uni.getStorageSync("token") || "");const userInfo = ref<UserInfo | null>(null);// 登录const login = async (username: string, password: string) => {const { tokenType, accessToken } = await AuthAPI.login(username, password);token.value = `${tokenType} ${accessToken}`; // Bearer tokenuni.setStorageSync("token", token.value);};// 获取用户信息const getUserInfo = async () => {const info = await UserAPI.getUserInfo();userInfo.value = info;};// 登出const logout = async () => {await AuthAPI.logout();userInfo.value = null;token.value = ""; // 清空 tokenuni.removeStorageSync("token"); // 从本地缓存移除 token};return {token,userInfo,login,logout,getUserInfo,};
});
个人中心页面
个人中心页面展示用户的头像和昵称,未登录时引导用户去登录。
<template><view class="flex-center flex-col"><text class="text-blue font-bold text-lg">我的</text><!-- 判断是否已登录 --><template v-if="isLoggedIn"><image :src="userInfo?.avatar" class="w100 h100 mb-5 rounded-full" /><text class="text-lg font-bold">{{ userInfo?.nickname }}</text><button @click="handleLogout" class="mt-5">退出登录</button></template><!-- 未登录时显示去登录按钮 --><template v-else><text>您还未登录,请先登录</text><button @click="goToLoginPage" class="mt-5">去登录</button></template></view>
</template><script lang="ts" setup>
import { useUserStore } from "@/store/modules/user";// 使用 pinia
const userStore = useUserStore();const isLoggedIn = computed(() => userStore.token);
const userInfo = computed(() => userStore.userInfo);// 跳转到登录页面
const goToLoginPage = () => {uni.navigateTo({ url: "/pages/login/index" });
};// 退出登录处理
const handleLogout = async () => {await userStore.logout();uni.showToast({ title: "已退出登录", icon: "success" });
};
</script>
登录页通过 Pinia
实现用户信息的全局状态管理,并在登录成功后跳转到个人中心页面。
<template><view class="flex-col items-center"><input v-model="username" placeholder="请输入用户名" /><input v-model="password" placeholder="请输入密码" type="password" /><button class="mt-5" @click="handleLogin">登录</button></view>
</template><script lang="ts" setup>
import { useUserStore } from "@/store/modules/user";// 登录表单
const username = ref("admin");
const password = ref("123456");// 使用 pinia
const userStore = useUserStore();// 登录处理
const handleLogin = async () => {await userStore.login(username.value, password.value);if (!!userStore.token) {await userStore.getUserInfo(); // 登录成功后获取用户信息uni.showToast({ title: "登录成功", icon: "success" });uni.navigateBack(); // 登录成功后返回上一页} else {uni.showToast({ title: "登录失败", icon: "none" });}
};
</script><style scoped>
input {width: 80%;padding: 10px;margin-top: 16px;border: 1px solid #ccc;
}
</style>
测试效果
登录后,个人中心会显示用户的头像和昵称。通过 Pinia 实现了登录状态的共享和跨页面传递。
整合源码
整合Pinia
代码版本:vue-uniapp-template#737f6a3。
反向代理
在开发中,若服务端没有启用 CORS(跨域资源共享),浏览器会基于安全策略拦截跨域请求,导致无法访问接口。为了绕过这个问题,我们可以通过 Vite 的反向代理功能,将开发阶段的请求代理到真实的 API 服务器上,伪装成同源请求。
本节将介绍如何配置 Vite 的反向代理来处理跨域请求。
环境变量配置
我们将通过环境变量来管理项目端口和 API 请求地址,以下是 .env.development
中的相关配置:
# .env.development# 项目运行的端口号
VITE_APP_PORT=5173# API 请求的基础路径(开发环境)
VITE_APP_BASE_API=/dev-api# 真实 API 服务器的 URL
VITE_APP_API_URL=https://api.youlai.tech
请求工具的调整
为了让请求走代理,我们需要在请求工具中将 VITE_APP_API_URL
替换为 VITE_APP_BASE_API
。这样,所有对 API
的请求都会通过代理标识 /dev-api
进行转发。
export default function request<T>(options: UniApp.RequestOptions): Promise<T> {return new Promise((resolve, reject) => {uni.request({...options,// 原请求方式: 使用真实 API URL// url: `${import.meta.env.VITE_APP_API_URL}${options.url}`, // 示例: https://api.youlai.tech/login// 修改后:使用代理标识,实际转发到真实 APIurl: `${import.meta.env.VITE_APP_BASE_API}${options.url}`, // 示例: http://localhost:5173/dev-api/login});});
}
Vite 反向代理配置
接下来,在 vite.config.ts
中添加反向代理配置,将 /dev-api
的请求代理到 VITE_APP_API_URL
,通过 http-proxy
实现请求的转发。
// vite.config.ts
import { defineConfig, UserConfig, ConfigEnv, loadEnv } from "vite";export default defineConfig(async ({ mode }: ConfigEnv): Promise<UserConfig> => {const env = loadEnv(mode, process.cwd());return {server: {host: "0.0.0.0",port: +env.VITE_APP_PORT,open: true,// 反向代理配置proxy: {[env.VITE_APP_BASE_API]: {target: env.VITE_APP_API_URL, // 目标服务器changeOrigin: true, // 支持跨域rewrite: (path) => path.replace(new RegExp("^" + env.VITE_APP_BASE_API), ""), // 去掉前缀},},},plugins: [// 插件配置...],};
});
测试与验证
在配置好反向代理后,浏览器发出的请求将被 Vite 的代理服务器拦截并转发至真实的 API 地址。例如,浏览器请求 http://localhost:5173/dev-api/api/v1/auth/login
时,Vite 会将该请求代理到 https://api.youlai.tech/api/v1/auth/login
。
下图展示了这一过程,浏览器认为请求的 URL 与应用的主机地址一致,因此不会阻止该请求,即便真实请求已通过代理转发到外部服务器。
需要注意,反向代理的目标是伪装请求来源,虽然它绕过了浏览器的同源策略,但有时也会让开发者误以为请求地址错误。实际上,这是由于代理转发过程造成的表面请求地址与真实请求地址的差异。
整合源码
整合反向代理
和环境变量
代码版本:vue-uniapp-template#272d643。
整合 wot-design-uni
wot-design-uni
是基于 Vue 3
和 TypeScript
构建的高质量组件库。组件库遵循 Wot Design
的设计规范,提供 70 多个组件,支持暗黑模式、国际化和自定义主题,旨在为开发者提供一致的 UI 交互,同时提高开发效率。
说明: 本文档整合步骤基于
wot-design-uni
官方文档编写,建议开发者参考 官方文档 进行安装和配置,以确保组件库的正确使用。
安装依赖
根据官方文档,使用 pnpm
安装组件库的依赖:
pnpm add wot-design-uni
配置自动引入组件
在传统的 Vue
项目中,使用组件需要手动安装、引用、注册。而使用 easycom
可以简化这些操作。只要组件路径符合规范,就可以直接在页面中使用,无需手动导入和注册。
在 pages.json
文件中配置 easycom
自动引入:
// pages.json
{"easycom": {"autoscan": true,"custom": {"^wd-(.*)": "wot-design-uni/components/wd-$1/wd-$1.vue"}},"pages": [// 这里是项目已有的内容]
}
关于 easycom
:
easycom
是 uni-app
提供的自动化引入功能,更多细节请参考 easycom 官方文档。
Volar 支持
为了让 Volar
正确识别和提示全局组件,你需要在项目的 tsconfig.json
文件中配置全局组件类型支持:
// tsconfig.json
{"compilerOptions": {"types": ["wot-design-uni/global"]}
}
这将确保你在 TypeScript
项目中编写代码时,Volar 能提供完整的类型支持和代码提示。
测试组件
安装和配置完成后,你可以开始使用 wot-design-uni
的组件。在页面中,直接写组件标签即可,无需手动导入和注册:
<template><view><wd-button size="small">主要按钮</wd-button><wd-button type="success" size="small">成功按钮</wd-button><wd-button type="info" size="small">信息按钮</wd-button><wd-button type="warning" size="small">警告按钮</wd-button><wd-button type="error" size="small">危险按钮</wd-button></view>
</template>
你将看到如下按钮效果:
整合源码
整合wot-design-uni
代码版本:vue-uniapp-template#a775721。
项目部署
H5 部署
执行 pnpm run build:h5
命令来完成项目的打包:
pnpm run build:h5
打包后生成的静态文件位于 dist/build/h5
目录下。将该目录下的文件复制到服务器的 /usr/share/nginx/html/vue-uniapp-template
目录。
接下来,配置 nginx:
# nginx.conf
server {listen 80;server_name localhost;location / {root /usr/share/nginx/html/vue-uniapp-template;index index.html index.htm;}# 反向代理配置location /prod-api/ {# 将 api.youlai.tech 替换为后端 API 地址,注意保留后面的斜杠 /proxy_pass http://api.youlai.tech/; }
}
这样配置完成后,就可以通过 nginx
服务器来访问你的项目了。
小程序发布
下载工具
下载 HBuilder X 编辑器
下载 微信开发者工具
获取小程序 AppID
访问 微信公众平台申请小程序,获取 AppID
。如果已申请,可在 首页
→ 小程序信息
→ 查看详情
查看 AppID
配置项目
使用 HBuilder X 打开项目,修改 manifest.json
文件中的小程序配置,并填写获取的 AppID。
设置微信开发者工具
使用微信扫码登录微信开发者工具,开启服务端口:点击工具栏设置
→安全设置
→安全
→服务端口
,选择打开。
运行项目
在 HBuilder X 中,点击 运行
→运行到小程序模拟器
→微信开发者工具
。
项目编译完成后,微信开发者工具会自动启动并呈现页面。
上传发布
在微信开发者工具中,点击 上传
将应用发布到小程序平台。
查看效果
最后,使用手机打开小程序查看效果:
结语
通过本文的详细讲解,相信你已经掌握了如何从零搭建一个高效的、基于 Vue3 和 TypeScript 的 UniApp 跨移动端解决方案脚手架模板——vue-uniapp-template。无论是代码规范、状态管理、样式配置,还是 Git 提交规范与项目部署,都能帮助你在实际项目中提高开发效率和代码质量。
希望本文能为你的项目开发提供全面的指导与支持,助你快速搭建出一个高效的跨移动端解决方案。Happy 1024 & Happy Coding!
附:项目源码
本篇文章涉及的源码已开源,项目地址:https://gitee.com/youlaiorg/vue-uniapp-template ,项目正在努力建设中,希望有兴趣参与开源的小伙伴们联系我(haoxianrui)。
相关文章:

万字图文实战:从0到1构建 UniApp + Vue3 + TypeScript 移动端跨平台开源脚手架
🚀 作者主页: 有来技术 🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot 🍃 vue-uniapp-template 🌺 仓库主页: Gitee 💫 Github …...

在WebStorm遇到Error: error:0308010C:digital envelope routines::unsupported报错时的解决方案
作者:CSDN-PleaSure乐事 欢迎大家阅读我的博客 希望大家喜欢 使用环境:WebStorm 目录 介绍 解决 分析 方法一:设置环境变量 使用WebStorm 使用其他编译器 方法二:使用nvm切换nodejs版本 方法三:更新依赖版本 介…...

数据库产品中SQL注入防护功能应该包含哪些功能
数据库产品中 SQL 注入防护功能应包含以下几方面: 输入验证与过滤功能: 数据类型和格式验证:检查用户输入的数据是否符合预期的数据类型,比如对于一个应该是整数类型的字段,检查输入是否为整数;对于字符串…...

Ribbon客户端负载均衡策略测试及其改进
文章目录 一、目的概述二、验证步骤1、源码下载2、导入IDE3、运行前修改配置4、策略说明5、修改策略 三、最终结论四、改进措施1. 思路分析2. 核心代码3. 测试页面 一、目的概述 为了验证Ribbon客户端负载均衡策略在负载节点失效的情况下,是否具有故障转移的功能&a…...

linux网络编程5——Posix API和网络协议栈,使用TCP实现P2P通信
文章目录 Posix API和网络协议栈,使用TCP实现P2P通信1. socket()2. bind()3. listen()4. connect()5. accept()6. read()/write(), recv()/send()7. 内核tcp数据传输7.1 TCP流量控制7.2 TCP拥塞控制——慢启动/拥塞避免/快速恢复/快速重传 8. shutdown()9. close()9…...

低代码平台中的功能驱动开发:模块化与领域设计
在现代软件开发中,尤其是在低代码平台的背景下,清晰地定义功能和模块是成功的关键。功能驱动开发强调功能的优先性,模块化设计则确保系统的可维护性和可扩展性。本文将探讨如何在低代码平台中有效地将功能与模块结合起来,形成一个…...

HTTP和HTTPS基本概念,主要区别,应用场景
HTTP和 HTTPS是用于在网络中传输数据的协议,虽然它们的功能类似,但在安全性上存在显著差异。 1. HTTP 的基本概念 定义:HTTP 是一种无状态的、面向请求-响应的协议,用于客户端(如浏览器)和服务器之间传输…...

node.js使用Sequelize ORM操作数据库
一、什么是ORM ORM是在数据库和编程语言之间建立一种映射关系,这样可以让我们有非常简单的代码,来实现各种数据库的操作。 例如:使用mysql去查找表(表名称为Articles) SELECT * FROM Articles;但是我们使用ORM的话&…...

STM32-Modbus协议(一文通)
Modbus协议原理 RT-Thread官网开源modbus RT-Thread官方提供 FreeModbus开源。 野火有移植的例程。 QT经常用 libModbus库。 Modbus是什么? Modbus协议,从字面理解它包括Mod和Bus两部分,首先它是一种bus,即总线协议,和…...

100. 不同方向的投影视图
本节课给大家讲解,通过UI按钮界面交互改变threejs相机的观察视角。 x轴方向观察 // 通过UI按钮改变相机观察角度 document.getElementById(x).addEventListener(click, function () {camera.position.set(500, 0, 0); //x轴方向观察camera.lookAt(0, 0, 0); //重新…...

Appium中的api(三)
目录 Appium中的api(三) 1.输入和清空内容 1--输入内容 2--清空内容 2.获取文本内容 3.获取文本位置 4.获取文本的大小(即获取控件的宽和高) 5.滑动api 6.拖拽api 7.如何获取手机分辨率 8.如何截图 9.模拟按键事件api 10.操作通知栏 案例:App自动化模拟 …...

踩坑:关于使用ceph pg repair引发的业务阻塞
概述 在某次故障回溯中,发现引发集群故障,slow io,pg stuck的罪魁祸首竟是做了一次ceph pg repair $pgid。然而ceph pg repair作为使用频率极高的,用来修复pg不一致的常用手段,平时可能很少注意其使用规范和可能带来的…...

瞬间升级!电子文档华丽变身在线题库,效率翻倍✨
👋嘿小伙伴们,有个超赞的秘籍要告诉你们——土著刷题能将你的电子文档一键变身在线题库!😉 你还没发现这个宝藏功能吗?快来瞧瞧! 🌟是不是常被一堆电子版的学习资料搞得头昏脑涨,学习…...

如何动态改变本地的ip
在当今数字化时代,网络连接已成为我们日常生活和工作中不可或缺的一部分。无论是出于隐私保护、突破地域限制,还是为了测试和优化网络应用,动态改变本地IP地址的需求日益增多。本文将详细介绍如何安全、有效地实现这一目标,旨在帮…...

Spring Boot框架在中小企业设备管理中的创新应用
4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式,是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示: 图4-1系统工作原理…...

Ceph入门到精通-Osd db扩容
ceph-bluestore-tool 是一个在 BlueStore 实例上执行低级管理操作的实用程序。 以下命令可用于 ceph-bluestore-tool 语法 ceph-bluestore-tool COMMAND [ --dev DEVICE … ] [ -i OSD_ID ] [ --path OSD_PATH ] [ --out-dir DIR ] [ --log-file | -l filename ] [ --deep ]c…...

windows msvc2017 x64编译AWS SDK CPP库
在本文中,我们将介绍如何编译AWS SDK C库,以便在您的项目中使用。AWS SDK C库提供了与Amazon Web Services交互的接口,允许您在C应用程序中使用AWS服务。 一、准备工作 在开始编译AWS SDK C库之前,请确保您的系统已经安装了以下…...

铜业机器人剥片 - SNK施努卡
SNK施努卡有色行业电解车间铜业机器人剥片 铜业机器人剥片技术是针对传统人工剥片效率低下、工作环境恶劣及生产质量不稳定的痛点而发展起来的自动化解决方案。 面临人工剥片的诸多挑战,包括低效率、工作环境差、人员流动大以及产品质量控制不精确等问题。 人工剥片…...

非接触式竖向位移、水平位移视频实时在线监测的设备分类及选型
前言 视觉是人工智能正在快速发展的一个分支,简单说来,机器视觉就是用机器代替人眼来做测量和判断。在结构健康自动化监测方面,机器视觉采用光学图像结合智能算法和物联网技术,利用先进的智能靶标识别及亚像素处理等技术ÿ…...

Svelte 5 正式发布:新一代前端框架!
10 月 22 日,Svelte 5 正式发布!该版本带来的更新主要包括: 重写框架:Svelte 5 是从头开始重写的,使得应用更快、更小、更可靠,并且代码更一致和符合习惯。 向后兼容:Svelte 5 几乎完全向后兼容…...

85.【C语言】数据结构之顺序表的中间插入和删除及遍历查找
目录 3.操作顺序表 1.分析中间插入函数 函数的参数 代码示例 图片分析 main.c部分改为 在SeqList.h添加SLInsert函数的声明 运行结果 2.分析中间删除函数 函数的参数 代码示例 图片分析 main.c部分改为 在SeqList.h添加SLErase函数的声明 运行结果 承接84.【C语…...

触觉智能Purple Pi OH鸿蒙开发板成功适配OpenHarmony5.0 Release,开启新征程!
10月22日,触觉智能Purple Pi OH鸿蒙开发板迎来了重大系统版本升级,成功适配OpenHarmony5.0 Release,为嵌入式开发者和科技爱好者们带来了全新的机遇与挑战! 触觉智能 Purple Pi OH 开发板一直以来都以其高品质和超高性价比而著称。…...

分布式解决方案---分布式ID
目录 是什么 特点 全局唯一 高并发 高可用 怎么做 实现方案 是什么 分布式ID是指在分布式系统中生成的唯一标识符。由于分布式系统的特点,多个节点可能会同时生成ID,因此需要确保每个ID在整个系统中是唯一的。 重点就是唯一性!&#x…...

httpd服务
文章目录 1、搭建一个网络yum源2、基于域名访问的虚拟主机3、基于端口来访问域名4、搭建个人网站5、加密访问显示自定义网页内容 1、搭建一个网络yum源 [roottest01 conf.d]# cat repo.conf <virtualhost *:80>documentroot /var/www/html/ServerName 10.104.43.154ali…...

Linux系统安装Redis详细操作步骤(二进制发布包安装方式)
安装方式介绍 在Linux系统中,安装软件的方式主要有四种,这四种安装方式的特点如下: 安装方式特点二进制发布包安装软件已经针对具体平台编译打包发布,只要解压,修改配置即可rpm安装软件已经按照redhat的包管理规范进…...

Jenkins和Gitlab整合构建CI/CD流水线
配置环境 虚拟机建议4G起步 192.168.58.199 192.168.58.200 部署Jenkins 部署Jenkins参考这篇文章:Jenkins安装部署_connecting to pkg.jenkins.io (pkg.jenkins.io)|151.-CSDN博客 安装完毕之后根据下图操作 选择git,添加git仓库克隆url,选…...

14 C语言中的关键字
C语言中的关键字 在C语言中,关键字是一些预定义的单词,它们具有特殊的意义和用途。这些关键字不能用作标识符,比如变量名、函数名等,因为它们被保留用于特定的语言结构和操作。 关键字的分类 C语言的关键字可以分为几个主要类别…...

(11)(2.1.7) FETtec OneWire ESCs(一)
文章目录 前言 1 去哪里买 2 连接 3 组态 前言 !Note 此功能在固件版本 4.1.1 及更高版本上可用。 OneWire 是 FETtec 的 ESC 双向通信协议(ESC bi-directional communication protocol)。 FETtec OneWire ESC 的遥测信息被发送回自动驾驶仪: 电…...

Python 异步编程:使用 `asyncio.to_thread` 和 `asyncio.Queue` 处理任务队列
Python 异步编程:使用 asyncio.to_thread 和 asyncio.Queue 处理任务队列 1. 什么是 asyncio.to_thread?2. 什么是 asyncio.Queue?3. 示例代码:使用 asyncio.to_thread 和 asyncio.Queue 处理任务队列示例代码代码解释运行结果 4.…...

【问题解决】Flink在linux上运行成功但是无法访问webUI界面
一,问题 在搭建Flink的时候,已经在linux服务器上运行了./start-cluster.sh, 而且日志显示已经成功了。 服务器上也没有开启防火墙 正常来说应该能通过ip:8081来访问(8081是Flink WebUI的默认端口),但是访问的时候,显示…...