• 手把手搭建Vue3+Vite项目模板


    1、前言

    项目是一个基于 Vite3 搭建的 Vue3 项目模板,集成了 TypeScriptESLintPrettierStylelintHuskyCommitlintpnpm包管理工具、element-plusVue RouterPiniaSVG图标配置、SASSAxios等等。

    运行环境: VSCodeNode16+VSCode 插件:TypeScript Vue Plugin (Volar)Vue Language Features (Volar)Prettier - Code formatter

    注意:需要关闭 Vetur 插件

    2、搭建后台管理系统模板

    2.1 项目初始化

    今天来带大家从0开始搭建一个vue3版本的后台管理系统。一个项目要有统一的规范,需要使用eslint+stylelint+prettier来对我们的代码质量做检测和修复,需要使用husky来做commit拦截,需要使用commitlint来统一提交规范,需要使用preinstall来统一包管理工具。

    下面我们就用这一套规范来初始化我们的项目,集成一个规范的模版。

    2.1.1环境准备

    • node v16.14.2
    • pnpm 8.0.0

    2.1.2初始化项目

    本项目使用vite进行构建,vite官方中文文档参考:https://cn.vitejs.dev/guide/

    pnpm: performant npm ,意味“高性能的 npm”。pnpmnpm/yarn衍生而来,解决了npm/yarn内部潜在的bug,极大的优化了性能,扩展了使用场景。被誉为“最先进的包管理工具”

    pnpm安装指令

    npm i -g pnpm
    
    • 1

    项目初始化命令:

    pnpm create vite
    
    • 1

    进入到项目根目录pnpm install安装全部依赖.安装完依赖运行程序:pnpm run dev

    运行完毕项目跑在http://127.0.0.1:5173/,可以访问你得项目啦!

    2.2 项目配置

    2.2.1 eslint配置

    eslint中文官网:http://eslint.cn/

    ESLint最初是由Nicholas C. Zakas 于2013年6月创建的开源项目。它的目标是提供一个插件化的javascript代码检测工具

    首先安装eslint

    pnpm i eslint -D
    
    • 1

    生成配置文件:.eslint.cjs

    npx eslint --init
    
    • 1
    .eslint.cjs配置文件
    
    module.exports = {
       //运行环境
        "env": { 
            "browser": true,//浏览器端
            "es2021": true,//es2021
        },
        //规则继承
        "extends": [ 
           //全部规则默认是关闭的,这个配置项开启推荐规则,推荐规则参照文档
           //比如:函数不能重名、对象不能出现重复key
            "eslint:recommended",
            //vue3语法规则
            "plugin:vue/vue3-essential",
            //ts语法规则
            "plugin:@typescript-eslint/recommended"
        ],
        //要为特定类型的文件指定处理器
        "overrides": [
        ],
        //指定解析器:解析器
        //Esprima 默认解析器
        //Babel-ESLint babel解析器
        //@typescript-eslint/parser ts解析器
        "parser": "@typescript-eslint/parser",
        //指定解析器选项
        "parserOptions": {
            "ecmaVersion": "latest",//校验ECMA最新版本
            "sourceType": "module"//设置为"script"(默认),或者"module"代码在ECMAScript模块中
        },
        //ESLint支持使用第三方插件。在使用插件之前,您必须使用npm安装它
        //该eslint-plugin-前缀可以从插件名称被省略
        "plugins": [
            "vue",
            "@typescript-eslint"
        ],
        //eslint规则
        "rules": {
        }
    }
    
    • 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
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    vue3环境代码校验插件

    # 让所有与prettier规则存在冲突的Eslint rules失效,并使用prettier进行代码检查
    "eslint-config-prettier": "^8.6.0",
    "eslint-plugin-import": "^2.27.5",
    "eslint-plugin-node": "^11.1.0",
    # 运行更漂亮的Eslint,使prettier规则优先级更高,Eslint优先级低
    "eslint-plugin-prettier": "^4.2.1",
    # vue.js的Eslint插件(查找vue语法错误,发现错误指令,查找违规风格指南
    "eslint-plugin-vue": "^9.9.0",
    # 该解析器允许使用Eslint校验所有babel code
    "@babel/eslint-parser": "^7.19.1",
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    安装指令

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

    修改.eslintrc.cjs配置文件

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

    .eslintignore忽略文件

    dist
    node_modules
    
    • 1
    • 2

    运行脚本

    package.json新增两个运行脚本

    "scripts": {
        "lint": "eslint src",
        "fix": "eslint src --fix",
    }
    
    • 1
    • 2
    • 3
    • 4

    2.2.2 配置prettier

    有了eslint,为什么还要有prettiereslint针对的是javascript,他是一个检测工具,包含js语法以及少部分格式问题,在eslint看来,语法对了就能保证代码正常运行,格式问题属于其次;而prettier属于格式化工具,它看不惯格式不统一,所以它就把eslint没干好的事接着干,另外,prettier支持包含js在内的多种语言。

    总结起来,eslintprettier这俩兄弟一个保证js代码质量,一个保证代码美观。

    安装依赖包

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

    .prettierrc.json添加规则

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

    .prettierignore忽略文件

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

    通过pnpm run lint去检测语法,如果出现不规范格式,通过pnpm run fix 修改

    2.2.3 配置stylelint

    stylelint为css的lint工具。可格式化css代码,检查css语法错误与不合理的写法,指定css书写顺序等。

    我们的项目中使用scss作为预处理器,安装以下依赖:

    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 stylelint-config-standard-scss -D
    
    • 1

    .stylelintrc.cjs配置文件

    官网:https://stylelint.bootcss.com/

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

    .stylelintignore忽略文件

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

    运行脚本

    "scripts": {
    	"lint:style": "stylelint src/**/*.{css,scss,vue} --cache --fix"
    }
    
    • 1
    • 2
    • 3

    最后配置统一的prettier来格式化我们的jscsshtml代码

    "scripts": {
    	"dev": "vite --open",
    	"build": "vue-tsc && vite build",
    	"preview": "vite preview",
    	"lint": "eslint src",
    	"fix": "eslint src --fix",
    	"format": "prettier --write \"./**/*.{html,vue,ts,js,json,md}\"",
    	"lint:eslint": "eslint src/**/*.{ts,vue} --cache --fix",
    	"lint:style": "stylelint src/**/*.{css,scss,vue} --cache --fix"
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    当我们运行pnpm run format的时候,会把代码直接格式化

    2.2.4 配置husky

    在上面我们已经集成好了我们代码校验工具,但是需要每次手动的去执行命令才会格式化我们的代码。如果有人没有格式化就提交了远程仓库中,那这个规范就没什么用。所以我们需要强制让开发人员按照代码规范来提交。

    要做到这件事情,就需要利用husky在代码提交之前触发git hook(git在客户端的钩子),然后执行pnpm run format来自动的格式化我们的代码。

    安装husky

    pnpm install -D husky
    
    • 1

    执行

    npx husky-init
    
    • 1

    会在根目录下生成个一个.husky目录,在这个目录下面会有一个pre-commit文件,这个文件里面的命令在我们执行commit的时候就会执行

    .husky/pre-commit文件添加如下命令:

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

    当我们对代码进行commit操作的时候,就会执行命令,对代码进行格式化,然后再提交。

    2.2.5 配置commitlint

    对于我们的commit信息,也是有统一规范的,不能随便写,要让每个人都按照统一的标准来执行,我们可以利用commitlint来实现。

    安装包

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

    添加配置文件,新建commitlint.config.cjs(注意是cjs),然后添加下面的代码:

    module.exports = {
      extends: ['@commitlint/config-conventional'],
      // 校验规则
      rules: {
        'type-enum': [
          2,
          'always',
          [
            'feat',
            'fix',
            'docs',
            'style',
            'refactor',
            'perf',
            'test',
            'chore',
            'revert',
            'build',
          ],
        ],
        'type-case': [0],
        'type-empty': [0],
        'scope-empty': [0],
        'scope-case': [0],
        'subject-full-stop': [0, 'never'],
        'subject-case': [0, 'never'],
        'header-max-length': [0, 'always', 72],
      },
    }
    
    • 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
    • 28
    • 29

    package.json中配置scripts命令

    # 在scrips中添加下面的代码
    {
    "scripts": {
        "commitlint": "commitlint --config commitlint.config.cjs -e -V"
      },
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    配置结束,现在当我们填写commit信息的时候,前面就需要带着下面的subject

    'feat',//新特性、新功能
    'fix',//修改bug
    'docs',//文档修改
    'style',//代码格式修改, 注意不是 css 修改
    'refactor',//代码重构
    'perf',//优化相关,比如提升性能、体验
    'test',//测试用例修改
    'chore',//其他修改, 比如改变构建流程、或者增加依赖库、工具等
    'revert',//回滚到上一个版本
    'build',//编译相关的修改,例如发布版本、对项目构建或者依赖的改动
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    配置husky

    npx husky add .husky/commit-msg 
    
    • 1

    在生成的commit-msg文件中添加下面的命令

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

    当我们 commit 提交信息时,就不能再随意写了,必须是 git commit -m 'fix: xxx' 符合类型的才可以,需要注意的是类型的后面需要用英文的 :,并且冒号后面是需要空一格的,这个是不能省略的

    2.2.6 强制使用pnpm包管理器工具

    团队开发项目的时候,需要统一包管理器工具,因为不同包管理器工具下载同一个依赖,可能版本不一样,

    导致项目出现bug问题,因此包管理器工具需要统一管理!!!

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

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

    配置命令

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

    当我们使用npm或者yarn来安装包的时候,就会报错了。原理就是在install的时候会触发preinstall(npm提供的生命周期钩子)这个文件里面的代码。

    3、项目集成

    3.1 集成element-plus

    官网地址:https://element-plus.gitee.io/zh-CN/

    安装element-plus

    pnpm install element-plus @element-plus/icons-vue
    
    • 1

    入口文件main.ts全局安装element-plus, element-plus默认支持语言英语设置为中文

    import ElementPlus from 'element-plus';
    import 'element-plus/dist/index.css'
    //@ts-ignore忽略当前文件ts类型的检测否则有红色提示(打包会失败)
    import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
    app.use(ElementPlus, {
       locale: zhCn
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    Element Plus全局组件类型声明

    // tsconfig.json
    {
    	"compilerOptions": {
    	  // ...
    	  "types": ["element-plus/global"]
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    配置完毕可以测试element-plus组件与图标的使用。

    3.2 集成 Vue Router

    安装vue-router

    pnpm i vue-router@4
    
    • 1

    路由配置

    // `src\router\index.ts`
    // 通过vue-router插件实现模板路由配置
    import { createRouter, createWebHashHistory } from 'vue-router'
    import { constantRoute } from './router'
    //创建路由器
    const router = createRouter({
      //路由模式hash
      history: createWebHashHistory(),
      routes: constantRoute,
      //滚动行为
      scrollBehavior() {
        return {
          left: 0,
          top: 0,
        }
      },
    })
    export default router
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    // `src\router\router.ts`
    // 对外暴露配置路由(常量路由)
    export const constantRoute = [
      {
        //登录路由
        path: '/login',
        component: () => import('@/views/login/index.vue'),
        name: 'login', //命名路由
      },
      {
        //登录成功以后展示数据的路由
        path: '/',
        component: () => import('@/views/home/index.vue'),
        name: 'layout',
      },
      {
        path: '/404',
        component: () => import('@/views/404/index.vue'),
        name: '404',
      },
      {
        //重定向
        path: '/:pathMatch(.*)*',
        redirect: '/404',
        name: 'Any',
      },
    ]
    
    • 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

    路由出口

    src\App.vue
    
    • 1

    在这里插入图片描述

    3.3 集成 Pinia

    安装pinia:pnpm i pinia@2.0.34

    // `src\store\index.ts`
    // 仓库大仓库
    import { createPinia } from 'pinia'
    //创建大仓库
    const pinia = createPinia()
    //对外暴露:入口文件需要安装仓库
    export default pinia
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    // `src\store\modules\user.ts`
    //创建用户相关的小仓库
    import { defineStore } from 'pinia'
    //创建用户小仓库
    const useUserStore = defineStore('User', {
      //小仓库存储数据地方
      state: () => {},
      //处理异步|逻辑地方
      actions: {},
      getters: {},
    })
    //对外暴露小仓库
    export default useUserStore
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3.4 src别名的配置

    在开发项目的时候文件与文件关系可能很复杂,因此我们需要给src文件夹配置一个别名!!!

    // vite.config.ts
    import {defineConfig} from 'vite'
    import vue from '@vitejs/plugin-vue'
    import path from 'path'
    export default defineConfig({
        plugins: [vue()],
        resolve: {
            alias: {
                "@": path.resolve("./src") // 相对路径别名配置,使用 @ 代替 src
            }
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    TypeScript 编译配置

    // tsconfig.json
    {
      "compilerOptions": {
        "baseUrl": "./", // 解析非相对模块的基地址,默认是当前目录
        "paths": { //路径映射,相对于baseUrl
          "@/*": ["src/*"] 
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.5 环境变量的配置

    项目开发过程中,至少会经历开发环境、测试环境和生产环境(即正式环境)三个阶段。不同阶段请求的状态(如接口地址等)不尽相同,若手动切换接口地址是相当繁琐且易出错的。于是环境变量配置的需求就应运而生,我们只需做简单的配置,把环境状态切换的工作交给代码。

    开发环境(development

    顾名思义,开发使用的环境,每位开发人员在自己的dev分支上干活,开发到一定程度,同事会合并代码,进行联调。

    测试环境(testing

    测试同事干活的环境啦,一般会由测试同事自己来部署,然后在此环境进行测试

    生产环境(production

    生产环境是指正式提供对外服务的,一般会关掉错误报告,打开错误日志。(正式提供给客户使用的环境。)

    注意:一般情况下,一个环境对应一台服务器,也有的公司开发与测试环境是一台服务器!!!

    项目根目录分别添加 开发、生产和测试环境的文件!

    .env.development
    .env.production
    .env.test
    
    • 1
    • 2
    • 3

    文件内容

    # 变量必须以 VITE_ 为前缀才能暴露给外部读取
    NODE_ENV = 'development'
    VITE_APP_TITLE = 'XX平台'
    VITE_APP_BASE_API = '/dev-api'
    
    
    NODE_ENV = 'production'
    VITE_APP_TITLE = 'XX平台'
    VITE_APP_BASE_API = '/prod-api'
    
    
    # 变量必须以 VITE_ 为前缀才能暴露给外部读取
    NODE_ENV = 'test'
    VITE_APP_TITLE = 'XX平台'
    VITE_APP_BASE_API = '/test-api'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    配置运行命令:package.json

    "scripts": {
      "dev": "vite --open",
      "build:test": "vue-tsc && vite build --mode test",
      "build:pro": "vue-tsc && vite build --mode production",
      "preview": "vite preview"
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    通过import.meta.env获取环境变量

    3.6 SVG图标配置

    在开发项目的时候经常会用到svg矢量图,而且我们使用SVG以后,页面上加载的不再是图片资源,这对页面性能来说是个很大的提升,而且我们SVG文件比img要小的很多,放在项目中几乎不占用资源。

    安装SVG依赖插件

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

    vite.config.ts中配置插件

    import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
    import path from 'path'
    export default () => {
      return {
        plugins: [
          createSvgIconsPlugin({
            // Specify the icon folder to be cached
            iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
            // Specify symbolId format
            symbolId: 'icon-[dir]-[name]',
          }),
        ],
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    入口文件导入

    import 'virtual:svg-icons-register'
    
    • 1

    svg封装为全局组件

    因为项目很多模块需要使用图标,因此把它封装为全局组件!!!

    src/components目录下创建一个SvgIcon组件:代表如下

    <template>
      <div>
        <svg :style="{ width: width, height: height }">
          <use :xlink:href="prefix + name" :fill="color"></use>
        </svg>
      </div>
    </template>
    
    <script setup lang="ts">
    defineProps({
      //xlink:href属性值的前缀
      prefix: {
        type: String,
        default: '#icon-'
      },
      //svg矢量图的名字
      name: String,
      //svg图标的颜色
      color: {
        type: String,
        default: ""
      },
      //svg宽度
      width: {
        type: String,
        default: '16px'
      },
      //svg高度
      height: {
        type: String,
        default: '16px'
      }
    
    })
    </script>
    <style scoped></style>
    
    • 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
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    src文件夹目录下创建一个index.ts文件:用于注册components文件夹内部全部全局组件!!!

    import SvgIcon from './SvgIcon/index.vue';
    import type { App, Component } from 'vue';
    const components: { [name: string]: Component } = { SvgIcon };
    export default {
        install(app: App) {
            Object.keys(components).forEach((key: string) => {
                app.component(key, components[key]);
            })
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在入口文件引入src/index.ts文件,通过app.use方法安装自定义插件

    import gloablComponent from './components/index';
    app.use(gloablComponent);
    
    • 1
    • 2

    3.7 集成sass

    我们目前在组件内部已经可以使用scss样式,因为在配置styleLint工具的时候,项目当中已经安装过sass sass-loader,因此我们再组件内可以使用scss语法!!!需要加上lang="scss"

    <style scoped lang="scss"></style>
    
    • 1

    接下来我们为项目添加一些全局的样式

    src/styles目录下创建一个index.scss文件,当然项目中需要用到清除默认样式,因此在index.scss引入reset.scss

    @import reset.scss
    
    • 1

    在入口文件引入

    import '@/styles'
    
    • 1

    但是你会发现在src/styles/index.scss全局样式文件中没有办法使用变量.因此需要给项目中引入全局变量。
    style/variable.scss创建一个variable.scss文件!

    vite.config.ts文件配置如下:

    export default defineConfig((config) => {
    	css: {
          preprocessorOptions: {
            scss: {
              javascriptEnabled: true,
              additionalData: '@import "./src/styles/variable.scss";',
            },
          },
        },
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    @import "./src/styles/variable.less";后面的;不要忘记,不然会报错!

    配置完毕你会发现scss提供这些全局变量可以在组件样式中使用了!!!

    3.8 axios二次封装

    在开发项目的时候避免不了与后端进行交互,因此我们需要使用axios插件实现发送网络请求。在开发项目的时候

    我们经常会把axios进行二次封装。

    目的:

    1:使用请求拦截器,可以在请求拦截器中处理一些业务(开始进度条、请求头携带公共参数)

    2:使用响应拦截器,可以在响应拦截器中处理一些业务(进度条结束、简化服务器返回的数据、处理http网络错误)

    在根目录下创建utils/request.ts

    import axios from "axios";
    import { ElMessage } from "element-plus";
    //创建axios实例
    let request = axios.create({
        baseURL: import.meta.env.VITE_APP_BASE_API,
        timeout: 5000
    })
    //请求拦截器
    request.interceptors.request.use(config => {
        return config;
    });
    //响应拦截器
    request.interceptors.response.use((response) => {
        return response.data;
    }, (error) => {
        //处理网络错误
        let msg = '';
        let status = error.response.status;
        switch (status) {
            case 401:
                msg = "token过期";
                break;
            case 403:
                msg = '无权访问';
                break;
            case 404:
                msg = "请求地址错误";
                break;
            case 500:
                msg = "服务器出现问题";
                break;
            default:
                msg = "无网络";
    
        }
        ElMessage({
            type: 'error',
            message: msg
        })
        return Promise.reject(error);
    });
    export default request;
    
    • 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
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
  • 相关阅读:
    简单讲解ANSI Unicode、GBK、GB2312
    Net6.0项目发布到IIS 503
    一、T100应付管理之基础数据设置篇
    【排序算法】常见排序算法总结
    [附源码]SSM计算机毕业设计学术文献分享网站JAVA
    计算机毕业设计Java架构校园二手物品交易(源码+系统+mysql数据库+lw文档)
    解决注册Kaggle出现的“Captcha must be filled out”问题
    【andriod】APP登录设备云FlexManager平台API接口
    PWR电源控制
    【Spring Boot系列】- Spring Boot事务应用详解
  • 原文地址:https://blog.csdn.net/DZQ1223/article/details/132905813