「Vue3初探」- 搭建一套完整的vue3前端框架,需要做哪些工作?

2,734 阅读15分钟

2022年2月7日,vue3成为了vue的默认版本,这意味着基于vue3的生态将要活跃于前端圈了,最近项目也不算太忙,因此利用业余时间,搭建了一套完整的vue3框架,从基于vite的快速搭建,到规范的制定,来看一下,在业务代码开始前,需要做哪些工作吧?

一、快速开始

vue3官网上介绍了使用create-vue脚手架快速搭建vue项目的示例,这里我们提供一种基于vite构建项目的方式。

vite搭建

vite是一个构建前端框架的新工具,其采用原生 ESM 机制,利用rollup进行打包,基于 esbuild 预构建依赖,开箱即用。利用vite创建一个项目,主要步骤如下:

  1. 命令终端下进入到某个文件目录,如D:/vueProject
  2. 通过yarn create vite命令,创建项目。
  3. 根据提示选择创建的项目模板、是否使用ts等。根据项目需要自行选择。
  4. yarn create vite vite-of-vue --template vue,也可用该命令生成项目。生成之后目录如下,与以往vue项目不同,index.html是在根目录下的,而非public目录下,除此之外,index.html中加载main文件,是type/module格式的。

二、项目辅助工具

2.1、vue-devtools

vue-devtools是vue项目的调试神器,通过该工具可以直观的看到vue相关属性、方法、状态等变化。其安装方式有两种,第一种通过浏览器的扩展程序下载安装,但这种从google商店下载,需要翻墙才能实现。第二种,则是通过clone源码形式,进行安装。这里重点介绍第二种方法。

  1. 从github上clone代码到本地,vue-devtools的git地址
  2. 拉取到的代码,通过开发工具打开,执行 yarn install 命令,安装项目依赖包。
  3. 安装完成后,在packages中找到shell-chrome项目。
  4. 浏览器中输入 chrome://extensions/, 打开开发者模式,将shell-chrome拖入其中,如下图可看见vue图标了。

2.2、volar工具使用

volar作为vue3最完美的配套神器,在功能上与vetur是一致的,作为vue的插件,它最重要的作用是对typescript提供了一流的支持。同时还对vue文件高亮展示,提供了对style、template、scripts的可视化快捷分割,并且对sugar ref、style中class的引用也都提供了支持。毕竟volar作为有尤大亲自推荐的神器,优点自然不用说。

  1. 在vscode的扩展中,搜索volar,进行安装。
  2. 安装后,在vue文件上方会出现volar的小图标,点点该图标,就能看到惊喜哦。

三、开发语言、样式、接口、路由配置

搭建好的vue框架,通常还需要第三方的支撑,如开发语言的设置、样式选择、调用接口工具、路由信息配置等。这些配置好后,在开发阶段才能更加得心应手。

3.1、typescript支撑

github上统计了21年第4季度编程语言的使用趋势,可以看到typescript持续保持上升趋势,其在类型检测方向的优秀特性,也让它越来越受开发者的欢迎。

image.png 我们都知道,支持typescript是vue2的硬伤,在vue3中,vite天然支持引入.ts文件,在快速创建项目那里也介绍过,我们可以直接在创建项目时,选择安装vue-ts,安装好之后,我们就可以使用ts开发项目。

3.2、样式文件支撑

在vue3中,可以通过@import对.css文件导入。同时也可以根据自己的编码习惯,引入.sass,.less,.stylus等文件。vite对这些文件提供了内置支持,我们不需要为其安装对应插件,但是需要安装相应的预处理器依赖。

  1. npm add -D sass 安装sass、scss依赖。
  2. npm add -D less 安装less依赖。
  3. npm add -D stylus 安装stylus、styls依赖。 安装之后,在vue文件中,通过lang='****'属性定义,同时和vue2项目一样,为了保持css的私有属性,需要添加scoped关键字。 除了选择合适的css预处理器之外,对于样式文件的文档结构也可以进行设计,通常,我们将公用样式、第三方文件样式、颜色属性、动画特性等独立成单独的文件夹,对css文件进行分层,更清晰明了,便于维护。

3.3、路由配置

前端项目通常都是通过不同的路径来对页面进行控制的,而路由则定义了路径与页面的映射关系,vue3对应的配套路由则是vue-router 4,在项目中安装vue-router,同时在main.ts中引入。

  1. yarn add vue-router --dev安装插件
  2. 在main.ts中,通过import引入。
  3. 在main.ts中,配置vue-router路由信息,同时使用app.use调用。
// 引入vueRouter
import * as VueRouter from "vue-router";
// 配置路由信息
const router = VueRouter.createRouter({
  history: VueRouter.createWebHashHistory(),
  routes,
});
// use调用
app.use(router)

这里在对路由文件进行引入的时候,需要考虑层次关系,如果这是一个多系统复用同个login、404、个人信息修改等页面的项目,可以将这些公共页面配置在公共路由如publicRouter文件中,而业务系统对应的功能页面配置在systemRouter中。这样可以保证路由层级关系清晰。这里我也在同步做一个共用组件库,会将公用路由信息提取到公用组件库中,后续业务系统只需要配置业务路由即可完成整个路由信息的配置工作。

3.4、状态管理

在项目中,有的数据会在不同组件或者不同页面间共享,这时候需要使用到状态管理机制。状态管理方面,vue3默认版本为vuex4,vuex4的安装与使用与vuex3相似,不再赘述。这里讲解下Pinia,pinia是以Composition API 为基础建立的新状态管理器,是Vuex 的继承者。pinia与vuex的使用区别,后面会出文章详细介绍。

  1. yarn add pinia --dev安装pinia。
  2. 在main.ts中,通过import引入。
  3. 在main.ts中调用,app.use(createPinia())。 pinia使用方式主要基于两步,定义store与使用store
  4. defineStore()创建store,state、getters、actions都在这里配置。
  5. useStore()在组件中使用store。
// 定义store,在pinia中已经去除了mutaions
import { defineStore } from "pinia"
const useStore = defineStore("storeTest", {
	state: () => ({
		count: 0,
		msg: "hello world",
	}),
	getters: {},
	actions: {},
})
export default useStore
// 在.vue文件中使用store,同时可以更改store内容
<script setup lang="ts">
    import useStore from "../stores/storeTest"
    const store = useStore()
    store.count += 1
    store.msg += " developers"
</script>
<template>
	<div>{{ store.count }}</div>
	<div>{{ store.msg }}</div>
</template>

3.5、接口封装

在接口调用方面,选择axios。vue3融合axios的方式与vue2有些区别,vue3的composition API由于没有了this和prototype,因此在开发时要改变使用习惯,vue3可以将axios挂载在全局变量中,或者使用vue-axios插件来处理。当然,除了这种方式之外,也可以不在main.ts中注入,直接在index.ts中封装所有接口,在vue文件中调用接口即可,但这种方式缺少模块化的概念,同时代码会冗长,因此这里主要介绍下其他两种方法。

  • 挂载到全局变量globalProperties
  1. yarn add axios --dev安装axios。
  2. 在main.ts中,将axios挂载到globalProperties中。这里的globalProperties和vue2中的Vue.prototype类似。
  3. 在vue文件中使用axios。
// main.ts中挂载axios
import { createApp } from "vue"
import axios from "axios"
const app = createApp(App)
app.config.globalProperties.$axios = axios
// 在vue文件中使用
import { ComponentInternalInstance, getCurrentInstance } from "vue"

const { appContext } = getCurrentInstance() as ComponentInternalInstance
console.log(appContext?.config.globalProperties.$axios)

可以注意到,这里我们使用到了typescript的类型断言。这里主要是因为getCurrentInstance()返回类型存在null,因此使用类型断言来规避。

image.png

  • 使用vue-axios插件 由于axios插件缺少install方法,而vue中,需要使用use插件必须要提供install,如果想使用app.use形式引入的话,可以使用vue-axios插件,同时结合provide inject方式使用。
  1. yarn add vue-axios --dev使用命令安装vue-axios,注意这里也同时需要安装axios
  2. 在main.ts中直接使用app.use(VueAxios, axios),利用provide共享属性。
  3. 在vue文件中,通过inject使用。
// main.ts中,使用provide共享axios
import axios from "axios"
import VueAxios from "vue-axios"

app.use(VueAxios, axios)
app.provide("axios", app.config.globalProperties.axios)
// vue文件中,通过inject使用
import { inject } from "vue"
const axios: any = inject("axios")

四、规范

为什么在搭建项目时,需要考虑到规范?想必大家都曾遇到过这样一个问题,我们在提交代码的时候,通常会因为空格符多少的问题,而出现冲突。这种空格符不同的问题,往往是因为个人代码习惯造成的,如果项目中没有针对代码规范的一些规则,则可能会花大量的时间在处理这些不必要的问题上。

代码规范通常分为代码质量代码风格两大类,代码质量往往会针对语法、变量定义方式等进行验证,而代码风格往往会对代码的格式进行验证,而我们在项目中,通常使用eslint来管理代码质量,prettierrc来统一代码规范。

4.1、代码质量规范eslint

eslint主要是用于检查javascript代码的,这里肯定有人会提出疑问,typescript本身就是检测javascript的,那为什么还要使用eslint呢?我们知道ts主要对代码的类型进行检测,而eslint除了类型检测之外,还提供一种统一代码风格。因此两者其实在功能上有重合的地方,但eslint在代码风格方面又进行了相应补充。项目中如何使用eslint呢?

  1. 首先需要在项目路径下,安装eslint。 yarn add eslint --dev
  2. 在终端中输入./node_modules/.bin/eslint --init命令,根据提示回答提出的问题,选择符合项目的选项,比如选择使用到的框架是vue还是react,使用的代码风格是什么?当回答了相应问题后,eslint会推荐必须安装的第三方依赖。安装完成后,会在项目根路径下生成.eslintrc.js文件,该文件中会有对应的配置属性,如plugins配置了使用到的第三方插件、rules提供了需要定义的规则、extends则配置了使用到的基础规则等。
  3. 在.eslintrc.js文件的rules选项中,可以自定义自己的规则。 通过第2步的选择,eslint会寻找对应的安装包,进行安装。其中,针对vue会安装eslint-plugin-vue插件。 vscode中集成eslint插件在旧版本中,由于eslint插件默认是不检查.ts后缀的文件,因此需要在.vscode/settings.js文件中配置eslint.validate属性,才能生效。但在新版本中,已经不再需要任何的配置,eslint.probe属性已经规定了ESlint插件需要校验的语言类型。
// 旧版本中,需要配置
// .vscode/setting.json
{
    "eslint.validate": [
        "javascript",
        "javascriptreact",
        "vue",
        "typescript"
    ]
}

还可以设置.eslintignore.js文件,用于忽略部分不需要代码检测的文件。具体配置规则可以查询官网。

4.2、代码风格规范prettier

Prettier官网介绍自己是一个“有态度”的代码格式化工具,可以知道它主要工作就是处理代码格式。它可以弥补eslint中没有完善的代码格式问题。eslint+prettierrc,一个侧重代码质量问题,对潜在的可能引发bug的代码进行检测,一个侧重代码格式问题,将代码格式统一管理,两者结合,能够给团队提供完善的代码规范管理。

  • 处理冲突

项目中通过yarn add prettier --dev命令安装prettier。由于eslint中的部分格式规则和prettier中的规则可能会发生冲突,因此需要安装eslint-config-prettier来关闭eslint中可能引起冲突的配置。通过命令yarn add eslint-config-prettier --dev安装,然后在extends属性中配置。这里需要把prettier放置在最后。

  // .eslintrc.js中的配置
  extends: [
    'plugin:vue/vue3-essential', // eslint-plugin-vue中的规则扩展
    'airbnb-base',
    'prettier',
  ],

处理完冲突之后,就能完全使用prettier中的规则了,但按照prettier的介绍,如果需要使用其规则,需要在.prettierrc.json文件中进行配置,对于项目来说维护两套配置文件容易发生混乱,因此我们可以通过eslint-plugin-prettier插件,将它集成在eslint中,让eslint作为统一问题来源来检测代码。

  1. yarn add eslint-config-prettier --dev安装插件。
  2. 在.eslintrc.js中,给plugins属性,增加prettier
  3. 在rules中,可以使用prettier/规则名的形式,添加prettier的规则。

4.3、代码提交规范

除了开发代码时候需要制定规范,在提交代码时,保持统一的注释风格,可以让团队在问题定位、代码回退等方面更加可控。这里介绍一种基于commlint、husky、lint-stagedconventional-changelog结合的管理风格,其中,commlint定义了提交规范、husky挂载执行操作、lint-staged指定对暂存区文件执行检测、conventional-changelog生成CHANGELOG.md 变更文档。

  • 定义规范commitlint commitlint工具可以检验commit格式是否符合规范,通过安装commitlint包含的工具来规范commit提交信息。
  1. yarn add @commitlint/config-conventional @commitlint/cli --dev执行该命令安装依赖。
  2. 新建commitlint.config.js文件,配置规范,这里直接使用默认的。
// 提交格式 git commit -m <type>(<scope>?): <subject>
// scope可选项,定义当前改动文件范围,如src/views/helloWorld.vue
// subject:必填项,制定提交内容
// type类型如下表:必填项

module.exports = {
  extends: ["@commitlint/config-conventional"],
};
类型 含义
build主要目的是修改项目构建系统的提交
ci主要目的是修改项目继续集成流程的提交
docs文档更新
feat新增功能
fixbug 修复
perf性能优化
refactor重构代码(既没有新增功能,也没有修复 bug)
style不影响程序逻辑的代码修改(修改空白字符,补全缺失的分号等)
test新增测试用例或是更新现有测试
revert回滚某个更早之前的提交
chore不属于以上类型的其他类型
  • 指定何时执行规范husky

定义完规范信息之后,可以和husky配合使用用于检测git操作时涉及到的代码。husky官网可查看具体信息。我们在package.json文件中配置husky,如果出现了husky失效问题,需要从以下两方面检查,1、检查执行git init操作与安装husky的顺序,git init需要首先执行。2、检查yarn的版本问题,yarn 1与yarn 2安装不一样。这里提供的是yarn 1的安装方式

  1. 在终端中,执行git init。初始化为一个git项目。
  2. 安装husky。yarn add husky --dev
  3. 执行npm set-script prepare "husky install"命令,作用是安装完husky后自动启用钩子,这步执行后会在package.json文件的scripts中新增prepare指令。scripts增加了prepare指令
  4. 执行yarn husky add .husky/pre-commit "yarn dev",创建一个钩子对应的指令。这里为了测试husky是否生效,我创建了一个pre-commit的钩子,并执行了启动项目的指令。这步执行后,会在根目录下生成.husky的文件夹。commit指令是否成功
  5. 执行git add .husky/pre-commit将增加的钩子添加到git中。
  6. 执行commit命令,查看husky是否生效。commit指令是否成功
  • 范围细化到暂存区lint-staged lint-staged能够对git暂存区上的文件进行检测,它能够将检测范围细化到需要提交的文件上,确保在push前能够阻止不规范的代码入库。
  1. yarn add lint-staged --dev安装lint-staged。
  2. 在package.json文件中,配置lint-staged信息。commit指令是否成功
  3. 在package.json中,配置对应的lint-staged指令。
  4. 将lint-staged指令,配置到pre-commit钩子下,yarn husky add .husky/pre-commit "yarn lint-staged"。这里也可以点开.husky文件夹下的文件自动修改指令。lint-staged指令是否成功 上图可以看到,lint-staged并没有检测具体规则,因此,需要增加commit-msg钩子,在该钩子上,配置commlint相关指令,从而可以确保在commit之前,读取commitlint.config.js文件中的配置规则来检测代码。
  5. yarn husky add .husky/commit-msg "yarn commitlint --edit $1",新增commit-msg钩子。
  6. 将该钩子通过git add 命令增加到git中。commitlint指令是否成功

4.4、生成变更文档conventional-changelog

按照规范提交后,可配合 conventional-changelog 自动生成 CHANGELOG.md 变更文档,便于团队记录变更。

  1. yarn add conventional-changelog-cli --dev安装依赖。
  2. 配置对应的script脚本。"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0"
  3. 制定yarn changelog生成变更文档。

五、结语

做完上述工作后,就可以进行项目开发了,当然在开发过程中,还需要考虑当前项目是组件库,还是业务库,如果是组件库,还需要对项目插件化做额外工作,同时需要提供插件文档说明,可以使用VuePress提供类似官网的静态网站,如果是业务库的话,还需要考虑到项目打包与部署情况,这里后续再分章节介绍吧。

  • 后续需要补充的遗留项: 第三方组件重写、自定义组件库、mitt控制事件流、集成测试、项目压缩与部署、静态网站生成。 完整的项目结构图: