项目地址:
https://github.com/bubbletg/vite-vue3-ts

安装项目

通过 vite 初始化项目

https://cn.vitejs.dev/guide/#scaffolding-your-first-vite-project
安装

yarn create vite or npm create vite@latest

image.png
image.png

git init

使用 git init 对项目初始化。

使用ESlint代码规范

安装 ESlint

https://cn.eslint.org/docs/user-guide/getting-started
你可以使用 npm 安装 ESLint:

npm install eslint —save-dev

紧接着你应该设置一个配置文件:

./node_modules/.bin/eslint —init


image.png

vscode 安装 ESLinit

image.png

ESLint 对vue3 的验证插件支持

  1. 找到 eslint-plugin-vue 插件下的 configs 查看插件有哪些

详情查看:https://eslint.vuejs.org/user-guide/#usage
image.png

  1. 修改 .eslintrc.js

image.png
完成上面配置后,会出现如下错误提示:
image.png

解决ESLint 带来的错误提示(代码规范)

1. 针对vue 文件

在 .eslintrc.js 中添加

‘vue/setup-compiler-macros’:true

  1. module.exports = {
  2. env: {
  3. browser: true,
  4. es2021: true,
  5. 'vue/setup-compiler-macros': true
  6. },
  7. extends: ['plugin:vue/vue3-strongly-recommended', 'standard'],
  8. parserOptions: {
  9. ecmaVersion: 'latest',
  10. parser: '@typescript-eslint/parser',
  11. sourceType: 'module'
  12. },
  13. plugins: ['vue', '@typescript-eslint'],
  14. rules: {}
  15. }

2.针对 ts,js,vue,jsx 等文件

在 package.json 中添加

“lint”:”eslint —ext js,jsx,ts,tsx,vue src/ —fix”,

  1. "scripts": {
  2. "dev": "vite",
  3. "build": "vue-tsc --noEmit && vite build",
  4. "preview": "vite preview",
  5. "lint": "eslint --ext js,jsx,ts,tsx,vue src/ --fix"
  6. },
  7. "lint-staged": {
  8. "*.{js,jsx,ts,tsx,vue}": [
  9. "yarn lint",
  10. "git add"
  11. ]
  12. }

这样我们就可以通过 npm run lint 来进行修复。
我们也可以使用vscode 设置默认的格式化工具为 ESLint 来进行格式化,并处理一些代码规范报错。

代码提交执行 npm run lint 来对代码进行校验

使用 lint-staged 来解决这个问题。
安装:

npx mrm@2 lint-staged

image.png
出现上图表示成功了。
测试如下图,表示成功了。
image.png

让 vite 打包时候对代码格式进行校验

使用 vite-plugin-eslint 插件来完成,该插件是一个 vite 插件。
安装:

npm install vite-plugin-eslint —save-dev

配置:vite.config.ts

  1. import { defineConfig } from 'vite'
  2. import vue from '@vitejs/plugin-vue'
  3. import eslintPlugin from 'vite-plugin-eslint'
  4. // https://vitejs.dev/config/
  5. export default defineConfig({
  6. plugins: [vue(), eslintPlugin({})]
  7. })

测试:
image.png

git commit 规范

关于 git commit 规范 查看 Git Guide Angular提交信息规范

使用插件来校验 git commit 规范

conventional-changelog/commitlint

安装

macOS

npm install —save-dev @commitlint/{config-conventional,cli}

win

npm install —save-dev @commitlint/config-conventional @commitlint/cli

安装完成后,执行命令:

echo “module.exports = {extends: [‘@commitlint/config-conventional’]}” > commitlint.config.js yarn husky add .husky/commit-msg ‘yarn commitlint —edit $1’

如下图表示成功。
image.png
测试:
不按照规范提交会出现如下错误:
image.png

ts 类型检查

vite 只会对 .ts 文件进行转译工作,不过执行类型检查。

支持router, vuex,txs

支持router

  1. import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
  2. const routes: RouteRecordRaw[] = [
  3. {
  4. path: '/',
  5. name: 'Home',
  6. component: () => import('../views/home/HomeIndex.vue')
  7. },
  8. {
  9. path: '/login',
  10. name: 'Login',
  11. component: () => import('../views/login/LoginIndex.vue')
  12. }
  13. ]
  14. const router = createRouter({
  15. history: createWebHashHistory(),
  16. routes
  17. })
  18. export default router

支持 vuex

  1. import { InjectionKey } from 'vue'
  2. import { createStore, useStore as baseUseStore, Store } from 'vuex'
  3. // 声明自己的 store state
  4. export interface State {
  5. count: number,
  6. testkey: string
  7. }
  8. // 定义 injection key
  9. export const key: InjectionKey<Store<State>> = Symbol('store')
  10. export const store = createStore<State>({
  11. state () {
  12. return {
  13. count: 0,
  14. testkey: 'key'
  15. }
  16. },
  17. mutations: {
  18. increment (state) {
  19. state.count++
  20. }
  21. }
  22. })
  23. // 定义自己的 `useStore` 组合式函数
  24. export function useStore () {
  25. return baseUseStore(key)
  26. }
  1. /* eslint-disable no-unused-vars */
  2. import { ComponentCustomProperties } from 'vue'
  3. import { Store } from 'vuex'
  4. import { State } from './store'
  5. declare module '@vue/runtime-core' {
  6. // 为 `this.$store` 提供类型声明
  7. interface ComponentCustomProperties {
  8. $store: Store<State>
  9. }
  10. }

支持 tsx

https://cn.vitejs.dev/guide/features.html#jsx
https://github.com/vitejs/vite/tree/main/packages/plugin-vue-jsx
安装:

npm i -D @vitejs/plugin-vue-jsx

配置:

  1. // vite.config.js
  2. import vueJsx from '@vitejs/plugin-vue-jsx'
  3. export default {
  4. plugins: [
  5. vueJsx({
  6. // options are passed on to @vue/babel-plugin-jsx
  7. })
  8. ]
  9. }

项目路径支持别名

在 vue2 中,我们可以使用 @ 来作为别名,在 vue3 默认不支持,需要我们自己配置。
vite.config.ts

  1. import { defineConfig } from 'vite'
  2. import vue from '@vitejs/plugin-vue'
  3. import eslintPlugin from 'vite-plugin-eslint'
  4. import vueJsx from '@vitejs/plugin-vue-jsx'
  5. import path from 'path'
  6. // https://vitejs.dev/config/
  7. export default defineConfig({
  8. plugins: [vue(), vueJsx(), eslintPlugin({
  9. cache: false
  10. })],
  11. resolve: {
  12. alias: {
  13. '@': path.join(__dirname, 'src')
  14. }
  15. }
  16. })

因为使用的是 ts ,引入 path 是node 的,会报错,需要安装 @types/node

npm i -D @types/node

配置完后,还需在 tsconfig.json 中配置 paths

  1. {
  2. "compilerOptions": {
  3. "target": "esnext",
  4. "useDefineForClassFields": true,
  5. "module": "esnext",
  6. "moduleResolution": "node",
  7. "strict": true,
  8. "jsx": "preserve",
  9. "sourceMap": true,
  10. "resolveJsonModule": true,
  11. "esModuleInterop": true,
  12. "lib": ["esnext", "dom"],
  13. "isolatedModules": true,
  14. "types": ["vite/client"],
  15. "paths": {
  16. "@/*": ["./src/*"]
  17. }
  18. },
  19. "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
  20. }

支持样式

image.png

配置 vite.config.ts
通过 配置 vite.config.ts 的 css.preprocessorOptions.scss.additionalData ,这样就可以不用在每个vue 文件的style 中书写 @import “@/styles/variables.scss”; 了。

  1. import { defineConfig } from 'vite'
  2. import vue from '@vitejs/plugin-vue'
  3. import eslintPlugin from 'vite-plugin-eslint'
  4. import vueJsx from '@vitejs/plugin-vue-jsx'
  5. import path from 'path'
  6. export default defineConfig({
  7. plugins: [vue(), vueJsx(), eslintPlugin({
  8. cache: false
  9. })],
  10. resolve: {
  11. alias: {
  12. '@': path.join(__dirname, 'src')
  13. }
  14. },
  15. css: {
  16. preprocessorOptions: {
  17. scss: {
  18. additionalData: '@import "@/styles/variables.scss";'
  19. }
  20. }
  21. }
  22. })

axios 封装支持

安装

npm i axios

基本封装

src\utils\request.ts

  1. import axios, { AxiosRequestConfig } from 'axios'
  2. const request = axios.create({
  3. baseURL: 'https://shop.fe.lagou.com/api/admin'
  4. })
  5. request.interceptors.request.use(function (config) {
  6. return config
  7. }, function (err) {
  8. return Promise.reject(err)
  9. })
  10. request.interceptors.response.use(function (response) {
  11. return response
  12. }, function (err) {
  13. return Promise.reject(err)
  14. })
  15. export default <T=any>(config:AxiosRequestConfig) => {
  16. return request(config).then(res => {
  17. return res.data.data as T
  18. })
  19. }

使用

src\api\admin.ts

  1. import request from '@/utils/request'
  2. import { ILoginInfo } from './types/admin'
  3. /**
  4. * 得到登录信息
  5. * @returns
  6. */
  7. export const getLoginInfo = () => {
  8. return request<ILoginInfo>({
  9. method: 'get',
  10. url: '/login/info'
  11. })
  12. }

src\api\types\admin.ts

  1. /**
  2. * 登录信息
  3. */
  4. export interface ILoginInfo {
  5. logo_square: string
  6. logo_rectangle: string
  7. login_logo: string
  8. slide: string[]
  9. }

src\views\login\LoginIndex.vue

  1. <template>
  2. <h1>login</h1>
  3. <h2>{{ $store.state.count }}</h2>
  4. </template>
  5. <script setup lang="ts">
  6. import { getLoginInfo } from '@/api'
  7. import type { ILoginInfo } from '@/api/types'
  8. import { useStore } from '@/store'
  9. import { ref } from '@vue/runtime-core'
  10. const store = useStore()
  11. const list = ref<ILoginInfo['slide']>([])
  12. console.log('🚀 ~ file: LoginIndex.vue ~ line 14 ~ list', list)
  13. console.log(store.state.testkey)
  14. getLoginInfo().then(res => {
  15. console.log('🚀 ~ file: LoginIndex.vue ~ line 13 ~ getLoginInfo ~ res', res.login_logo)
  16. })
  17. </script>

配置eslint

.eslintrc.js

  1. module.exports = {
  2. env: {
  3. browser: true,
  4. es2021: true,
  5. 'vue/setup-compiler-macros': true
  6. },
  7. extends: ['plugin:vue/vue3-strongly-recommended', 'standard'],
  8. parserOptions: {
  9. ecmaVersion: 'latest',
  10. parser: '@typescript-eslint/parser',
  11. sourceType: 'module'
  12. },
  13. plugins: ['vue', '@typescript-eslint'],
  14. rules: {},
  15. overrides: [
  16. {
  17. // 对单个文件不使用驼峰命名法校验
  18. files: ['src/api/**/*.ts'],
  19. rules: {
  20. camelcase: 'off'
  21. }
  22. }
  23. ],
  24. globals: {
  25. defineProps: 'readonly',
  26. defineEmits: 'readonly',
  27. defineExpose: 'readonly',
  28. withDefaults: 'readonly'
  29. }
  30. }

环境变量的配置

https://cn.vitejs.dev/guide/env-and-mode.html#production-replacement

配置代理处理跨越

https://cn.vitejs.dev/config/#server-proxy