步骤总览
开发前配置
- 命令行使用 vite 生成项目模板
- 配置 TypeScript:
- tsconfig 配置
- 安装 ts 类型检查
- 集中处理请求【Axios 库】
- 分支管理保护与自动化的2种方式,1个必要
开始开发
- 配置环境文件
- 配置别名【可选】
- 配置路由
- 选择&调研组件库
- 配置主题文件
- 安装 CSS 预处理器
- 开发过程中与 vue3 开发文档相关的一些知识点
- 开发过程中常见的问题
- 在项目中写出可维护可拓展的类型
结尾提供了其他相关链接
准备工作
使用 nvm 切换不同版本的 node 来适用不同项目
命令行使用 vite 生成项目模板
1 | node -v |
配置 TypeScript
tsconfig.json 文件 增加 2 项配置
1 | { |
安装 ts 类型检查
打开 vite.config.ts 文件时 控制台就会报 failed to load the eslint library for the vite.config.ts 错误,这是因为本地 eslint 无法解析 ts 文件,需要安装 ts 依赖 & vite 不提供 ts 类型检查
1 | # 安装ts eslint 依赖 |
下载额外的
npm
包需要添加其他类型定义:1.安装npm i --save-dev @types/xxx
;2.在tsconfig.json
中添加``types`的配置『 由于 vite2 创建的 ts 项目中已添加默认的 types 定义,标明只使用该类型定义,所以如果需要其他类型(不在@vite/client 中),需要增加配置 』
1 | // tsconfig.json |
本项目使用 eslint:recommended 规范,如需修改请参照 tslint 官方提示
工作目录下新增
.eslintrc.js
文件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// 不含 eslint-plugin-vue 插件的配置
module.exports = {
root: true,
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint"],
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
};
// 包含 eslint-plugin-vue 插件的配置
module.exports = {
root: true,
parser: "vue-eslint-parser",
parserOptions: {
parser: "@typescript-eslint/parser",
ecmaVersion: 2020,
sourceType: "module",
ecmaFeatures: {
jsx: true,
tsx: true,
},
},
plugins: ["@typescript-eslint"],
extends: [
"plugin:vue/vue3-recommended",
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
],
};工作目录下新增
.eslintignore
文件1
2
3
4
5
6
7
8
9
10# don't ever lint node_modules
node_modules
# don't lint build output (make sure it's set to your correct build folder name)
dist
# don't lint nyc coverage output
coverage
# don't lint .vscode
.vscode
# don't lint .eslintrc.js
.eslintrc.js
配置请求 Axios 集中处理请求
定义
1 | // server/index.ts 文件 |
使用定义好的 post, get
等方法
1 | // const-api-path.ts |
分支管理保护与自动化
测试环境的发布分支只有 2 个: dev, hotfix
分支管理、保护的2种方式,1个必要
基础仓库影响范围较大,分别对应多个项目的不同阶段,则需要对该项目进行分支管理和保护,通常只保护3个主要分支: main, dev,hotfix
第一种方式
一个新需求的全部工作流程
- 新建功能分支,以
feature-
开头 - 功能开发结束给
dev
提merge request
- 代码审核结束成功合并到
dev
后,开始测试 - 通过测试后提交
merge request
到main
分支准备发布 - 发布成功且线上验收成功后,在最新提交上打
tag
, 并推送 tags - 保留该功能分支 2 周删除该分支对应的远程分支,以防后续开发功能分支越来越多
一个紧急修复的全部流程
git checkout hotfix
git pull
- 开始修复,修复结束后提交代码发布到测试环境测试
- 通过测试后提交 mr 到
main
分支准备发布 - 发布成功且线上验收成功后,在最新提交上打
tag
, 并推送 tags
第二种方式
一个主仓库分别由各个开发fork到自己的group, 主仓库只保留3个分支:main(稳定版本-线上环境), hotfix(紧急修复-发布测试环境), dev(开发时-发布测试环境), fork仓库完全由开发者自行管理
1 | # fork后的项目新增一个 remote |
开发
配置环境文件
- 构建包文件会通过环境文件来确定环境变量,在项目下新增:
.env.production
文件.env.development
文件.env.stagging
文件
配置别名【可选】
1 | import { defineConfig } from "vite"; |
配置路由
1 | yarn add vue-router@4 |
使用
1 | import HelloWorld from "@/components/hello-world.vue"; |
添加额外的 meta 字段的类型声明
1 | // augmenation.d.ts |
添加路由元信息声明
选择组件库 ☞ 本项目使用 ant-design-vue
, 所以选用 less, 方便覆盖默认主题
配置主题文件
1 | // 使用插件转换文件 |
安装 CSS 预处理器
请匹配 组件库 的选择
1 | # .scss and .sass |
替换 moment 为 dayjs
yarn add dayjs
ornpm i dayjs
在
vite.config
中添加 alias1
2
3
4
5
6
7{
resolve: {
alias: {
moment: 'dayjs'
}
},
}在
main.ts
文件里添加相关插件, 添加前后分别打包进行比较
1 | // main.ts |
开发过程中与 vue3 开发文档相关的一些知识点
响应式 API
reaåctive()
: 返回对象的响应式副本
SetUp & ref() || unRef() & toRefs()
SetUp(props, context) 逻辑块组合,可组合:生命周期函数/watch/computed
,返回对象,对象可包含 data/methods/computed
生命周期映射关系
-> usebeforeCreate
setup()
-> usecreated
setup()
beforeMount
->onBeforeMount
mounted
->onMounted
beforeUpdate
->onBeforeUpdate
updated
->onUpdated
beforeUnmount
->onBeforeUnmount
unmounted
->onUnmounted
errorCaptured
->onErrorCaptured
renderTracked
->onRenderTracked
renderTriggered
->onRenderTriggered
由于
props
是响应式的,所以不能使用ES6解构
,因为 解构是浅复制,非引用类型属性拷贝后会跟原 prop 属性脱离,是一个新的变量,没有响应性,引用类型的属性(数组,对象,函数)还会保持引用,这 2 种情况下解构后的变量响应性不统一 所以会消除 prop 的响应性,如果需要解构 prop,使用toRefs
若要获取传递给 setup() 的参数的类型推断,请使用
defineComponent
在 Setup 中使用 Router
请使用
useRouter()
||useRoute()
, 模板中可以访问$router
和$route
,所以不需要在 setup 中返回router
或route
userLink & RouterLink
: 内部行为已经作为一个组合式 API 函数公开
ts 相关
setup()
函数中,不需要将类型传递给 props 参数,因为它将从 props 组件选项推断类型refs()
1.初始值推断类型;2.传递一个泛型参数;3. 使用Ref<T>
替代ref
readtive()
使用接口(Interface
)computed
自动推断
与 Options api 一起使用
- 复杂的类型或接口使用 as 强制转换
注解返回类型
- computed 的类型难以推断 需要注解
注解 props
- 使用 PropType 强制转换构造函数
1 | import { defineComponent, PropType } from "vue"; |
- 由于 ts 的设计限制:涉及到为了对函数表达式进行类型推理,你必须注意·对象和数组的
validators
和default
值
1 | import { defineComponent, PropType } from "vue"; |
注解 emit
- 为触发的事件注解一个有效载荷。另外,所有未声明的触发事件在调用时都会抛出一个类型错误。
1 | const Component = defineComponent({ |
类型声明 refs
- 有时我们可能需要为 ref 的内部值指定复杂类型。我们可以在调用 ref 重写默认推理时简单地传递一个泛型参数
1 | const year = ref<string | number>("2020"); // year's type: Ref<string | number> |
类型声明 reactive
与
ref
的区别: 当变量基础类型时使用ref
, 引用类型-对象/数组等使用reactive
- 当声明类型 reactive property,我们可以使用接口
1 | import { defineComponent, reactive } from "vue"; |
开发过程中遇到的问题[TroubleShooting]
注意:vite2 自动构建 typescript 模板项目文件,部分同学会在 build 阶段报错,详情请移步
- error VueDX/TS: context.imports.add is not a function
- @vuedx/typecheck vite build error with
const FSP = require('fs/promises');
windows 系统的同学可将 build 打包命令由
vuedx-typecheck . && vite build
改为vite build && tsc
,ci 脚本内加一条:run: npx --no-install vuedx-typecheck
在ts
文件内使用 const xxx = require('xxx')
报错:require is not defined
已解决:
vite@2.4.1
已修复该错误,升级即可
UI 组件的问题
ant-design-vue 按需加载问题:
查看Imports using @ant-design/icons-vue should be importing the ESM versionand-design-vue 版本问题!!!现发现
form & input
组件在引入 es 包时一直报错The requesed module '/node_modules/is-mobile/index.js' is dose not provide an export named 'isMobile'
,遂升级至 2.1.1 版本,同时删除 vite.config 里 optimizeDeps 的 exclude 的配置,才能使用:
详见组件库依赖的 ismobilejs 存在兼容性问题
依赖强缓存
- 通过浏览器 devtools 的 Network 选项卡暂时禁用缓存;
- 重启 Vite dev server,使用 –force 标志重新打包依赖;
- 重新载入页面。