GitHub地址
https://github.com/wxd15750/vue3_admin_templete.git

项目使用用pnpm来进行操作

修改vue-cli的安装命令
C:\用户.vuerc文件,修改一下命令即可
image.png

如何创建一个项目

1.使用Vite脚手架创建

vite官网 https://cn.vitejs.dev/guide/
搭建Vite项目
使用npm命令

  1. $ npm create vite@latest

使用yarn

  1. $ yarn create vite

使用pnpm

  1. $ pnpm create vite

2.项目的配置

1.找到src目录

删除src下的style.css文件,在main.ts中删除导入的样式文件,main.ts文件为项目的入口文件
index.html中修改项目的名称,及标签栏显示的文字
清除App.vue的内容,重新创建一个新的模板,可以创建一个代码切片

2.vue3代码切片

代码切片:点击设置 — 用户代码片段 — 输入切片别名,复制如下代码

  1. {
  2. "Vue Init": {
  3. "prefix": "vue3",
  4. "description": "初始化Vue单文件组件模版",
  5. "body": [
  6. "<template>",
  7. " <div>",
  8. " </div>",
  9. "</template>",
  10. "<script lang=\"ts\">",
  11. " import { defineComponent } from 'vue';",
  12. " export default defineComponent({",
  13. " name:'$1'",
  14. " })",
  15. "</script>",
  16. "<script lang=\"ts\" setup>",
  17. "</script>",
  18. "",
  19. "<style lang=\"less\" scoped>",
  20. "</style>",
  21. ""
  22. ]
  23. }
  24. }

以后创建vue3的模板,直接输入vue3按回车即可

配置切片图示

3294babc7224040602c20d83c1a6d44.png
4bc923d78e6324740515aeaa5f7b5e1.png
003e64c7051be16346564e5a9c41b72.png

项目运行命令
  1. npm run dev

3.vue2的切片代码

  1. {
  2. // Place your 全局 snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
  3. // description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
  4. // is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
  5. // used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
  6. // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
  7. // Placeholders with the same ids are connected.
  8. // Example:
  9. // "Print to console": {
  10. // "scope": "javascript,typescript",
  11. // "prefix": "log",
  12. // "body": [
  13. // "console.log('$1');",
  14. // "$2"
  15. // ],
  16. // "description": "Log output to console"
  17. // }
  18. "Vue Init": {
  19. "prefix": "vue2",
  20. "description": "初始化Vue单文件组件模版",
  21. "body": [
  22. "<template>",
  23. " <div>",
  24. " </div>\n",
  25. "</template>\n",
  26. "<script>",
  27. "export default {",
  28. " name:'',",
  29. " components: {\n",
  30. " },",
  31. " props: {\n",
  32. " },",
  33. " data() {",
  34. " return {\n",
  35. " };",
  36. " },",
  37. " mounted() {\n",
  38. " },",
  39. "}",
  40. "</script>\n",
  41. "<style lang=\"${1:stylus}\">\n",
  42. "</style>\n",
  43. ""
  44. ]
  45. }
  46. }

项目启动命令
  1. npm run serve

4.自动打开浏览器

在项目的package.json文件中找到script配置项,写入以下命令

  1. "scripts": {
  2. "dev": "vite --open",//添加 --open
  3. "build": "vue-tsc && vite build",
  4. "preview": "vite preview"
  5. },

5.设置eslint语法校验

安装(我使用的是pnpm)

  1. pnpm i eslint -D

初始化

  1. npx eslint --init

如图示进行配置
image.png
image.png
image.png
image.png
image.png
image.png
image.png
选择使用的包管理工具,这里使用的是pnpm
image.png
执行完以上操作,会在目录文件中生成一个 .eslintrc.cjs配置文件
eslint.png
vue3环境代码校验插件

  1. pnpm install -D eslint-plugin-import eslint-plugin-vue eslint-plugin-node
  2. eslint-plugin-prettier eslint-config-prettier eslint-plugin-node @babel/eslint-parser

修改配置文件.eslintrc.cjs的内容

  1. // @see https://eslint.bootcss.com/docs/rules/
  2. module.exports = {
  3. env: {
  4. browser: true,
  5. es2021: true,
  6. node: true,
  7. jest: true,
  8. },
  9. /* 指定如何解析语法 */
  10. parser: 'vue-eslint-parser',
  11. /** 优先级低于 parse 的语法解析配置 */
  12. parserOptions: {
  13. ecmaVersion: 'latest',
  14. sourceType: 'module',
  15. parser: '@typescript-eslint/parser',
  16. jsxPragma: 'React',
  17. ecmaFeatures: {
  18. jsx: true,
  19. },
  20. },
  21. /* 继承已有的规则 */
  22. extends: [
  23. 'eslint:recommended',
  24. 'plugin:vue/vue3-essential',
  25. 'plugin:@typescript-eslint/recommended',
  26. 'plugin:prettier/recommended',
  27. ],
  28. plugins: ['vue', '@typescript-eslint'],
  29. /*
  30. * "off" 或 0 ==> 关闭规则
  31. * "warn" 或 1 ==> 打开的规则作为警告(不影响代码执行)
  32. * "error" 或 2 ==> 规则作为一个错误(代码不能执行,界面报错)
  33. */
  34. rules: {
  35. // eslint(https://eslint.bootcss.com/docs/rules/)
  36. 'no-var': 'error', // 要求使用 let 或 const 而不是 var
  37. 'no-multiple-empty-lines': ['warn', { max: 1 }], // 不允许多个空行
  38. 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
  39. 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
  40. 'no-unexpected-multiline': 'error', // 禁止空余的多行
  41. 'no-useless-escape': 'off', // 禁止不必要的转义字符
  42. // typeScript (https://typescript-eslint.io/rules)
  43. '@typescript-eslint/no-unused-vars': 'error', // 禁止定义未使用的变量
  44. '@typescript-eslint/prefer-ts-expect-error': 'error', // 禁止使用 @ts-ignore
  45. '@typescript-eslint/no-explicit-any': 'off', // 禁止使用 any 类型
  46. '@typescript-eslint/no-non-null-assertion': 'off',
  47. '@typescript-eslint/no-namespace': 'off', // 禁止使用自定义 TypeScript 模块和命名空间。
  48. '@typescript-eslint/semi': 'off',
  49. // eslint-plugin-vue (https://eslint.vuejs.org/rules/)
  50. 'vue/multi-word-component-names': 'off', // 要求组件名称始终为 “-” 链接的单词
  51. 'vue/script-setup-uses-vars': 'error', // 防止<script setup>使用的变量<template>被标记为未使用
  52. 'vue/no-mutating-props': 'off', // 不允许组件 prop的改变
  53. 'vue/attribute-hyphenation': 'off', // 对模板中的自定义组件强制执行属性命名样式
  54. },
  55. }

新建一个eslint忽略文件 .eslintignore,写入以下内容

  1. dist
  2. node_modules

在package.json文件中的script配置项中新增两个配置项

  1. "lint":"eslint src",
  2. "fix":"eslint src --fix"

6.配置prettier

安装包

  1. pnpm install -D eslint-plugin-prettier prettier eslint-config-prettier

在项目根目录新建 .prettierrc.json文件,写入以下配置

  1. {
  2. "singleQuote": true,
  3. "semi": false,
  4. "bracketSpacing": true,
  5. "htmlWhitespaceSensitivity": "ignore",
  6. "endOfLine": "auto",
  7. "trailingComma": "all",
  8. "tabWidth": 2
  9. }

忽略文件 .prettierignore

  1. /dist/*
  2. /html/*
  3. .local
  4. /node_modules/**
  5. **/*.svg
  6. **/*.sh
  7. /public/*

7.样式的操作

安装包

  1. pnpm add sass sass-loader stylelint postcss postcss-scss postcss-html stylelint-config-prettier stylelint-config-recess-order stylelint-config-recommended-scss stylelint-config-standard stylelint-config-standard-vue stylelint-scss stylelint-order -D

配置项

  1. module.exports = {
  2. extends: [
  3. 'stylelint-config-standard', // 配置stylelint拓展插件
  4. 'stylelint-config-html/vue', // 配置 vue 中 template 样式格式化
  5. 'stylelint-config-standard-scss', // 配置stylelint scss插件
  6. 'stylelint-config-recommended-vue/scss', // 配置 vue 中 scss 样式格式化
  7. 'stylelint-config-recess-order', // 配置stylelint css属性书写顺序插件,
  8. 'stylelint-config-prettier', // 配置stylelint和prettier兼容
  9. ],
  10. overrides: [
  11. {
  12. files: ['**/*.(scss|css|vue|html)'],
  13. customSyntax: 'postcss-scss',
  14. },
  15. {
  16. files: ['**/*.(html|vue)'],
  17. customSyntax: 'postcss-html',
  18. },
  19. ],
  20. ignoreFiles: [
  21. '**/*.js',
  22. '**/*.jsx',
  23. '**/*.tsx',
  24. '**/*.ts',
  25. '**/*.json',
  26. '**/*.md',
  27. '**/*.yaml',
  28. ],
  29. /**
  30. * null => 关闭该规则
  31. * always => 必须
  32. */
  33. rules: {
  34. 'value-keyword-case': null, // 在 css 中使用 v-bind,不报错
  35. 'no-descending-specificity': null, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器
  36. 'function-url-quotes': 'always', // 要求或禁止 URL 的引号 "always(必须加上引号)"|"never(没有引号)"
  37. 'no-empty-source': null, // 关闭禁止空源码
  38. 'selector-class-pattern': null, // 关闭强制选择器类名的格式
  39. 'property-no-unknown': null, // 禁止未知的属性(true 为不允许)
  40. 'block-opening-brace-space-before': 'always', // 要求在块的开大括号之前必须有一个空格或不能有空白符
  41. 'value-no-vendor-prefix': null, // 关闭 属性值前缀 --webkit-box
  42. 'property-no-vendor-prefix': null, // 关闭 属性前缀 -webkit-mask
  43. 'selector-pseudo-class-no-unknown': [
  44. // 不允许未知的选择器
  45. true,
  46. {
  47. ignorePseudoClasses: ['global', 'v-deep', 'deep'], // 忽略属性,修改element默认样式的时候能使用到
  48. },
  49. ],
  50. },
  51. }

配置忽略文件 .stylelintignore

  1. /node_modules/*
  2. /dist/*
  3. /html/*
  4. /public/*

在package.json文件中的script中添加以下代码

  1. "format": "prettier --write \"./**/*.{html,vue,ts,js,json,md}\"",
  2. "lint:eslint": "eslint src/**/*.{ts,vue} --cache --fix",
  3. "lint:style": "stylelint src/**/*.{css,scss,vue} --cache --fix",

8.配置husky(提交代码时的强制格式化)

安装husky

  1. pnpm install -D husky

执行(必须要git init以下项目文件,否则会报错)

  1. npx husky-init

安装lint-staged

  1. pnpm install -D lint-staged

在package.json中配置如下命令

  1. {
  2. "scripts": {
  3. "lint-staged": "lint-staged"
  4. },
  5. "lint-staged": {
  6. "**/*.{js,jsx,ts,tsx,vue}": [
  7. "eslint --fix",
  8. "stylelint --fix",
  9. "prettier --write",
  10. "git add"
  11. ],
  12. "*.{scss,less,styl,html}": [
  13. "stylelint --fix",
  14. "prettier --write"
  15. ]
  16. },
  17. }

执行完以上命令会生成一个.husky文件,在此文件pre-commit 文件中写入以下代码

  1. #!/usr/bin/env sh
  2. . "$(dirname -- "$0")/_/husky.sh"
  3. pnpm run format //看安装用的是那个包管理工具,本人用的是pnpm

此操作是为了团队开发提交代码,对代码的一些格式化处理

9.配置commitlint(代码提交仓库的规范)

安装包

  1. pnpm add @commitlint/config-conventional @commitlint/cli -D

新建一个文件,写入以下代码进行规则的验证与匹配 commitlint.config.cjs

  1. module.exports = {
  2. extends: ['@commitlint/config-conventional'],
  3. // 校验规则
  4. rules: {
  5. 'type-enum': [
  6. 2,
  7. 'always',
  8. [
  9. 'feat',
  10. 'fix',
  11. 'docs',
  12. 'style',
  13. 'refactor',
  14. 'perf',
  15. 'test',
  16. 'chore',
  17. 'revert',
  18. 'build',
  19. ],
  20. ],
  21. 'type-case': [0],
  22. 'type-empty': [0],
  23. 'scope-empty': [0],
  24. 'scope-case': [0],
  25. 'subject-full-stop': [0, 'never'],
  26. 'subject-case': [0, 'never'],
  27. 'header-max-length': [0, 'always', 72],
  28. },
  29. }

配置项的说明 :::info feat:新功能,新特性;
fix:修改bug;
docs:文档修改;
style:代码格式修改
refactor:代码重构
perf:优化相关,如提升性能
test:测试用例修改
chore:其他修改,如构建流程增加项目依赖、工具等
revert:回滚到上一个版本
build:编译相关的修改,如发布版本、对项目构建或者依赖的改动 ::: 配置husky

  1. npx husky add .husky/commit-msg

在生成的commit-msg文件中添加以下命令,提交代码的一个检验

  1. #!/usr/bin/env sh
  2. . "$(dirname -- "$0")/_/husky.sh"
  3. pnpm commitlint

注意:以后提交代码到远程仓库,必须携程如下格式

  1. git commit -m "fix: 说明的文字"

类型后面的冒号必须是英文,并且冒号后面需要一个空格,这是不能省略的

10.强制使用统一的包管理工具

在根目录创建scritps/ preinstall.js文件,添加以下内容

  1. if (!/pnpm/.test(process.env.npm_execpath || '')) {
  2. console.warn(
  3. `\u001b[33mThis repository must using pnpm as the package manager ` +
  4. ` for scripts to work properly.\u001b[39m\n`,
  5. )
  6. process.exit(1)
  7. }
  8. if (!/pnpm/.test(process.env.npm_execpath || '')) {
  9. console.warn(
  10. `\u001b[33mThis repository must using pnpm as the package manager ` +
  11. ` for scripts to work properly.\u001b[39m\n`,
  12. )
  13. process.exit(1)
  14. }

在package.json文件中写入如下命令

  1. "scripts": {
  2. "preinstall": "node ./scripts/preinstall.js",
  3. }

当使用npm/yarn安装依赖时,会报错,必须使用pnpm

11.setting.json文件的配置

在项目的根目录创建 .vscode文件,在此文件中新建setting.json文件,复制以下代码

  1. .vscode/setting.json
  2. {
  3. // 开启自动修复
  4. "editor.codeActionsOnSave": {
  5. "source.fixAll": false,
  6. "source.fixAll.eslint": true,
  7. "source.fixAll.stylelint": true
  8. },
  9. // 保存的时候自动格式化
  10. "editor.formatOnSave": true,
  11. // 默认格式化工具选择prettier
  12. "editor.defaultFormatter": "esbenp.prettier-vscode",
  13. // 配置该项,新建文件时默认就是space:2
  14. "editor.tabSize": 2,
  15. // stylelint校验的文件格式
  16. "stylelint.validate": ["css", "scss", "vue", "html"]
  17. }

3.项目初始化操作

解决ts假报错

在src下找vite-env.d.ts文件

  1. //解决ts文件引入vue文件出现红色警告问题
  2. declare module '*.vue' {
  3. import { defineComponent } from 'vue';
  4. const Component: ReturnType<typeof defineComponent>;
  5. export default Component;
  6. }

1.安装element-plus

pnpm install element-plus
安装完成需要在main.ts文件中进行一个 引入

  1. // 引入elements-plus
  2. import ElementPlus from 'element-plus'
  3. import 'element-plus/dist/index.css'
  4. // 引入国际化
  5. // @ts-ignore
  6. import zhCn from 'element-plus/dist/locale/zh-cn.mjs'

2.配置文件路径

在vite.config.ts中写入以下配置项

  1. import path from 'path'
  2. resolve:{
  3. alias:{
  4. "@":path.resolve('./src')
  5. }
  6. }

在tsconfig.json文件中写入以下配置项

  1. "compilerOptions" :{
  2. "baseUrl": "./",
  3. "paths": {
  4. "@/":["src/*"]
  5. }
  6. }

3.环境的配置

在项目的更目录创建以下三个文件

  1. .env.development 开发环境
  2. .env.production 生产环境
  3. .env.test 测试环境

.env.development 开发环境

  1. # 变量必须以 VITE_ 为前缀才能暴露给外部读取
  2. NODE_ENV = 'development'
  3. VITE_APP_TITLE = 'Vue3 + Ts + Vite 后台管理'
  4. VITE_APP_BASE_API = '/api' //接口api前缀
  5. VITE_SERVE = "http://xxxxx"

.env.production 生产环境

  1. NODE_ENV = 'production'
  2. VITE_APP_TITLE = 'Vue3 + Ts + Vite 后台管理'
  3. VITE_APP_BASE_API = 'http://XXXX'
  4. VITE_SERVE="http://xxxxx"

.env.test 测试环境

  1. NODE_ENV = 'test'
  2. VITE_APP_TITLE = 'Vue3 + Ts + Vite 后台管理'
  3. VITE_APP_BASE_API = '/test-api'
  4. VITE_SERVE="http://xxxx"

4.项目集成svg图标库

安装svg依赖

  1. pnpm install vite-plugin-svg-icons -D

在assets文件中新建一个icons文件夹,用来存放svg图标,使用方式:在组件中写入以下代码

  1. <!--图标的大小可以在svg上写style来控制 -->
  2. <svg>
  3. <use xlink:href="#icon-图标名称" fill="颜色名字"></use>
  4. </svg>

对图标的处理
因为项目中会用到大量的图标,因此可以封装成一个公共组件,注册成全局组件

  1. <template>
  2. <svg :style="{width,height}">
  3. <use :xlink:href="prefix + name" :fill="color"></use>
  4. </svg>
  5. </template>
  6. <script lang="ts">
  7. import { defineComponent } from 'vue';
  8. export default defineComponent({
  9. name:'SvgIcon'
  10. })
  11. </script>
  12. <script lang="ts" setup>
  13. defineProps({
  14. prefix:{
  15. type:String,
  16. default:'#icon-'
  17. },
  18. // 使用图标的名称
  19. name:String,
  20. // 接受父组件传递的颜色
  21. color:{
  22. type: String,
  23. default: ''
  24. },
  25. // 接受父组件传递的宽度
  26. width:{
  27. type:String,
  28. default:'16px'
  29. },
  30. // 接受父组件传递的高度
  31. height:{
  32. type:String,
  33. default:'16px'
  34. }
  35. })
  36. </script>
  37. <style lang="less" scoped>
  38. </style>
  39. /**
  40. 定义全局组件 在main.ts中
  41. 1.定义
  42. 2.注册
  43. 3.使用
  44. */
  45. //svg插件需要配置代码
  46. import 'virtual:svg-icons-register'
  47. // 定义全局组件
  48. //
  49. import SvgIcon from '@/components/SvgIcon/index.vue';
  50. // 全局注册
  51. app.component('SvgIcon',SvgIcon)

自定义插件实现全局组件的注册

  1. // 引入项目中所有的全局组件
  2. import SvgIcon from './SvgIcon/index.vue'
  3. import Pagination from './Pagination/index.vue'
  4. // 全局对象
  5. const allGloablComponent = {SvgIcon,Pagination}
  6. // 对外暴露插件对象
  7. export default {
  8. // 此方法必须是install
  9. install(app:any){
  10. // 注册项目全部的全局组件
  11. Object.keys(allGloablComponent).forEach(key => {
  12. console.log(allGloablComponent[key]);
  13. // 注册为全局组件
  14. app.component(key,allGloablComponent[key])
  15. })
  16. }
  17. }
  18. // 在main.ts中写入以下代码
  19. // 引入自定义插件对象:注册整个项目的全局组件
  20. // @ts-ignore
  21. import gloalComponent from '@/components'
  22. // 安装自定义插件
  23. app.use(gloalComponent)

5.集成sass

在src文件夹下创建一个styles文件,里面用来存放样式相关的文件

  1. // 在main.ts中写入以下代码
  2. // 清除默认样式
  3. import '@/styles/index.scss'
  4. // 在vite.config.ts中写入以下配置项
  5. // 样式全局变量的配置
  6. css: {
  7. preprocessorOptions: {
  8. scss: {
  9. javascriptEnabled: true,
  10. additionalData: '@import "./src/styles/variable.scss";',
  11. },
  12. },
  13. },

6.设置mock数据

安装依赖

  1. pnpm install -D vite-plugin-mock mockjs

4.axios的二次封装

在src下创建utils文件夹,新建request.ts文件,写入以下代码

  1. // 引入axios
  2. import axios from 'axios'
  3. // @ts-ignore
  4. import { ElMessage } from "element-plus";
  5. // 第一步:利用axios对象的create方法,去创建axios实例(其他的配置:基础路径、超时时间)
  6. const requeset = axios.create({
  7. // 基础路径
  8. baseURL: import.meta.env.VITE_APP_BASE_API,
  9. // 设置超时时间
  10. timeout: 5000,
  11. })
  12. // // 第二步:给request实例添加请求拦截器
  13. requeset.interceptors.request.use((config)=>{
  14. // 返回配置对象
  15. return config;
  16. })
  17. // 第三步:给request实例添加响应拦截器
  18. requeset.interceptors.response.use((response)=>{
  19. // 成功的回调
  20. // 简化数据
  21. return response.data
  22. },
  23. (error)=>{
  24. // 失败的回调:处理http网络错误
  25. // 定义一个变量,存储网络错误信息
  26. let message = '';
  27. // http状态码
  28. let status = error.response.status
  29. switch(status){
  30. case 401:
  31. message = 'TOKEN过期';
  32. break;
  33. case 403:
  34. message = '无权访问';
  35. break;
  36. case 404:
  37. message = '请求地址错误';
  38. break;
  39. case 500:
  40. message = '服务器出现问题';
  41. break;
  42. default:
  43. message = '网络出现错误';
  44. break;
  45. }
  46. // 提示错误信息
  47. ElMessage({
  48. type:'error',
  49. message
  50. })
  51. return Promise.reject(error);
  52. }
  53. )
  54. // 对外暴露
  55. export default requeset;

5.对API接口的统一管理

新建api文件夹,里面存放和发请求相关的文件

6.配置路由

命令
pnpm install vue-router
代码如下

  1. // 通过vue-router插件实现模板路由配置
  2. // @ts-expect-error
  3. import {createRouter,createWebHashHistory} from 'vue-router'
  4. // 创建路由器
  5. const router = createRouter({
  6. // 设置路由模式
  7. history:createWebHashHistory(),
  8. routes:[
  9. {
  10. // 首页
  11. path:'/',
  12. component:() => import('@/views/home/index.vue'),
  13. name:'Home'
  14. },
  15. {
  16. // 登录
  17. path:'/login',
  18. component:() => import('@/views/login/index.vue'),
  19. name:'Login'
  20. },
  21. {
  22. // 404页面
  23. path:'/404',
  24. component:() => import('@/views/404/index.vue'),
  25. name:'404'
  26. },
  27. {
  28. // 任意路由
  29. path:'/:pathMatch(.*)*',
  30. redirect:'/404',
  31. name:'Any'
  32. }
  33. ],
  34. // 滚动行为
  35. scrollBehavior () {
  36. return {
  37. left:0,
  38. top:0
  39. }
  40. }
  41. })
  42. export default router;
  43. // main.ts
  44. // 引入路由
  45. // @ts-expect-error
  46. import router from '@/router/index.ts'
  47. // 注册路由
  48. app.use(router)

在src下新建一个views文件,用来存放路由组件
在App.vue中写入以下代码

  1. <template>
  2. <div>
  3. <router-view></router-view>
  4. </div>
  5. </template>
  6. <script lang="ts">
  7. import { defineComponent } from 'vue'
  8. export default defineComponent({
  9. name: 'App',
  10. })
  11. </script>
  12. <script lang="ts" setup></script>
  13. <style lang="less" scoped></style>