【项目】基于Vue3.2+ElementUI Plus+Vite 通用后台管理系统

构建项目

环境配置

  1. 全局安装vue脚手架

    npm install -g @vue/cli-init
    
  2. 打开脚手架图形化界面

    vue ui
    

创建项目

  1. 在图形化界面创建项目
  2. 根据要求填写项目相关信息
  3. 选择手动配置
  4. 勾选配置项目
  5. 选择配置项目
  6. 然后我们就搭建完成啦🥳,构建可能需要一点时间,大家稍等久一会。

安装依赖

  1. 在右侧边栏找到依赖

  2. 安装axios依赖

  3. 运行项目

    npm run serve
    

配置git commit规范

什么是commit规范?

Git commit规范是指为了使版本控制更加清晰、易于追踪和维护,而在提交代码时遵循的一系列约定。一个良好的Git commit规范能够帮助团队成员理解每一次提交的目的和范围,同时便于后续的代码审查、问题追踪以及生成变更日志。

以下是一些常见的Git commit规范要点:

  • feat:添加新特性
  • fix:修复bug
  • docs:仅仅修改了文档
  • style:仅仅修改了空格、格式缩进、逗号等等,不改变代码逻辑
  • refactor:代码重构,没有加新功能或者修复bug
  • perf:优化相关,比如提升性能、体验
  • test:增加测试用例
  • chore:改变构建流程、或者增加依赖库、工具等
  • revert:回滚到上一个版本

下面是提交规范的配置步骤:

  1. 在vscode终端中,安装commitizen和cz-customizable

    npm install -g commitizen@4.2.4
    npm i cz-customizable@6.3.0--save-dev
    //如果第二个安装不成功可以使用下面这个
    npm i cz-customizable@6.3.0 --save-dev --force
    
  2. 在package.json中进行新增下面语句:

    "config": {
      "commitizen": {
        "path": "node_modules/cz-customizable"
      }
    }
    
  3. 在根目录下新建.cz-config.js文件并写入配置 之后就可以用 git cz 来代替 git commit

  4. 最后我们可以尝试git添加上传,再使用git cz检测是否安装成功

    //上传git
    git add .
    //git commit提交
    git cz
    
  5. 出现以下👇情况就是安装成功啦🥳

内容补充:

Commitizen的介绍:是一个用于撰写Git提交信息的工具。它可以帮助开发人员遵循一个规范,以便更容易地阅读和维护Git仓库历史记录。Commitizen采用了一个交互式的命令行界面,引导你逐步填写必要的数据,从而生成符合规范的Git提交信息。

cz-customizable的介绍:是一个Commitizen的插件,它允许你使用自定义的Git提交规范。通过为项目添加一个配置文件,你可以指定你自己的提交格式,并在使用Commitizen时使用该格式。你可以轻松地定义自己的提交类型、作用域和描述等信息。

配置强制commit规范

为什么需要强制约束commit规范?因为正常工作中多人协作的时候每个人的习惯不一样,所以我们需要强制性的进行规范化处理。

我们通过安装commitlint来实现强制性规范commit。

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

然后安装husky进行强制git代码提交规范。

npm install husky@7.0.1 --save-dev

最后对husky进行初始化。

npx husky install

如果在文件夹中出现了多出来了这一个文件就说明成功了🥳

问题补充:

如果安装commitlint未成功,可能是因为这是因为@vue/eslint-config-standard@6.1.0 依赖于 eslint-plugin-vue@^7.0.0,但是你的项目中已经安装了 eslint-plugin-vue@8.7.1,版本过高导致的。这里我也写了一片解决办法

别急!我们还有后续步骤:

  1. 添加commitlint.config.js文件到项目当中

  2. package.json文件中添加以下👇指令:

    "prepare": "husky install"
    
  3. 执行指令

    npm run prepare
    
  4. .husky中添加commit配置文件,在终端输入以下指令

    npx husky add .husky/commit-msg
    

    如果在这个文件夹中新增了这个commit文件就说明配置成功了

  5. 最后修改commit-msg文件,是为了hosky和commitlik实现关联

    npx --no-install commitlint --edit
    

强制规范我们就配置完啦,接下来测试一下

首先将文件添加到仓库当中:
	git add .
然后来一个不符合规矩的提交:
	git commit -m '这是不符合规矩的'
再来一个符合规矩的操作:
git add .
git commit -m 'feat: 符合规矩的'

这样强制规范我们就配置好啦🥳!!!

代码格式化

同样的,代码格式我们也要实现强制格式化,这样防止我们写着写着就忘记了代码规范,以免错乱。

  1. 执行指令添加代码强制格式化文件

    npx husky add .husky/pre-commit
    

    添加成功就会多出一个代码强制格式化文件出来:

  2. 在新增加的文件中写入下面这段话:

    npx lint-staged
    
  3. package.json文件中添加:

    "lint-staged": {
       "src/**/*.{js,vue}": [      //src目录下所有的js和vue文件
         "eslint --fix",           // 自动修复
         "git add"                 // 自动提交时修复
       ]
     }
     注意:上面的注释需要删掉!!!
    

安装UI组件库

这里我们使用到的是Element Plus UI组件库,这个是他的安装 | Element Plus (element-plus.org)地址。我这里也简要描述一下他的安装步骤:

  1. 在项目终端中执行安装组件库命令:

    npm install element-plus --save
    
  2. 按需导入组件

    npm install -D unplugin-vue-components unplugin-auto-import
    
  3. 创建vue.config.js文件,将以下👇代码导入

    //两个版本,如果第一个报错的话就用第二个,第二个是我自己找来配置的,建议先使用up提供的,这样才能保证与视频项目配置一致。
    
    const AutoImport = require('unplugin-auto-import/webpack')
    const Components = require('unplugin-vue-components/webpack')
    const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')
    
    module.exports = {
      configureWebpack: config => {
        config.plugins.push(AutoImport({
          resolvers: [ElementPlusResolver()],
        }))
        config.plugins.push(Components({
          resolvers: [ElementPlusResolver()],
        }))
      },
    }
    
    //第二个版本,我自己配置的(上面一个不可用,在使用我这个)
    const { defineConfig } = require('@vue/cli-service')
    const AutoImport = require("unplugin-auto-import/webpack");
    const Components = require("unplugin-vue-components/webpack");
    const { ElementPlusResolver } = require("unplugin-vue-components/resolvers");
    module.exports = defineConfig({
      transpileDependencies: true,
      configureWebpack: {
        plugins: [
          AutoImport({
            resolvers: [ElementPlusResolver()],
          }),
          Components({
            resolvers: [ElementPlusResolver()],
          }),
        ],
      },
    });
    
  4. 启动项目检验

    npm run serve
    

问题一:UI无法安装

如果Vs code安装UI组件库安装不了,是版本问题,在命令后面加上--legacy-peer-deps

问题二:启动项目报错

如果在启动检验项目的时候报错:

  1. ERROR TypeError: AutoImport is not a function

    unplugin-auto-import版本高了,降版本成0.16.7,这个问题就不报错了。

    npm install unplugin-auto-import@0.16.1 -force
    
  2. ERROR TypeError: Components is not a function

    unplugin-vue-components版本过高,回退插件版本。

     npm install unplugin-vue-components@0.25.2
    

如何查看是否生效呢?

我们可以在组件库里面引入几个按钮组件到Homeview.vue文件中,然后运行项目。组件按钮如果出现了就说明引入成功啦🥳🥳🥳

引入按钮组件的代码:

<el-button>Default</el-button>
<el-button type="primary">Primary</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">Info</el-button>
<el-button type="warning">Warning</el-button>
<el-button type="danger">Danger</el-button>

创建项目

Vue3.2新特性

下面我将介绍两个新特性:

第一个新特性就是不再需要
作为根目录。

在 Vue 3 中,特别是 Vue 3.2 版本,引入了一个新的 RFC (Request for Comments) 特性,即允许在单文件组件(SFC)的 <template> 中使用 <router-view> 作为根节点,而不再是必须使用 <div> 或其他元素作为根节点。这项特性是在 Vue Router 4 中实现的,它与 Vue 3 的 Composition API 和新的 <script setup> 语法糖相辅相成,提供了更灵活的路由视图设置。

这项改变允许开发者在 Vue 3 的单文件组件中这样写:

vue<template>
  <router-view/>
</template>

而不是必须将 <router-view> 包裹在一个 <div> 中:

vue复制<template>
  <div>
    <router-view/>
  </div>
</template>

第二个介绍的特性就是CSS可以直接绑定JS变量

在 Vue 3.2 版本中,引入了一项新特性,允许开发者直接在 CSS 中绑定 JavaScript 变量,这是通过 <style> 标签的 v-bind 属性实现的。这项特性特别适用于在使用 <script setup> 语法的单文件组件(SFC)中。

具体来说,你可以在 <style scoped><style module> 中使用 v-bind 来动态地应用 CSS 属性,这些属性的值可以是 JavaScript 表达式。例如:

vue<script setup>
import { ref } from 'vue';

const themeColor = ref('blue');
</script>

<template>
  <div :class="`color-${themeColor.value}`">Hello World</div>
</template>

<style scoped>
.color-blue {
  color: v-bind(themeColor);
}
</style>

在上面的示例中,color-blue 类的 color 属性会绑定到 themeColor 变量的值。当 themeColor 的值改变时,应用到 DOM 元素上的样式也会相应地更新。

初始化项目

先将App.vue文件里面一些没有用的文件和代码片段删掉。删完的代码如下:

<template>
  <router-view/>
</template>

<style lang="scss">

</style>

之后导入styles文件到项目中的src文件夹中,这个包包含了一些js的初始化操作以及一些Sass文件。

第三步在main.js当中导入index.scss文件。

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import '@/styles/index.scss'    //导入`index.scss`文件

createApp(App).use(store).use(router).mount('#app')

登录组件的实现

编写登录页面

  1. src下的views文件夹中创建一个login文件夹。并新建文件index.vue

  2. 在新建的文件书写一些内容

    <template>
        <div>
    			这是一个登录界面
        </div>
    </template>
    
    <script setup>
    
    </script>
    
    <style lang="scss" scoped>
    
    </style>
    
  3. 配置路由(转到srcrouter文件)

    //删掉后的文件内容
    // 路由配置文件
    import { createRouter, createWebHashHistory } from 'vue-router'
    const routes = [
      {
        //配置登录界面
        path: '/login',   //设置路径
        name: 'Login',    //设置名称
        component: () => import('../views/login/index.vue')     //导入文件
      }
    ]
    
    const router = createRouter({
      history: createWebHashHistory(),
      routes
    })
    
    export default router
    
  4. 删除以下👇这两个文件

如果这个时候发现出现了以下👇错误导致无法运行了:webpack compiled with 1 error

解决办法:

  1. 选中并打开"vue.config.js"

  2. 输入"lintOnSave:false"来关闭eslint校验

    lintOnSave:false
    
  1. 访问地址,因为是添加了路由,所以我们要在原来URL路径上添加login才能跳转到新添加的页面

编写页面

添加输入框

在登录页面文件中,引入一个表单组件

<template>
  <div class="login-container">
    <!-- 添加一个表单项 -->
    <el-form ref="form" :model="form" class="login-form">
        <div class="title-container">
            <h3 class="title">用户登录</h3>
        </div>
      <el-form-item>
        <el-input v-model="form.name"></el-input>
      </el-form-item>
    </el-form>
  </div>
</template>

创建双向数据绑定

<script setup>
  import { ref } from 'vue'
  const form = ref({
    name: ''
  })
</script>

添加图标

<template>
  <div class="login-container">
    <!-- 添加一个表单项 -->
    <el-form ref="formRef" :model="form" class="login-form">
      <div class="title-container">
        <h3 class="title">用户登录</h3>
      </div>
      <el-form-item>
        <!-- 添加图标 -->
        <el-icon :size="20" class="svg-container">
          <edit />
        </el-icon>
        <el-input v-model="form.username"></el-input>
      </el-form-item>
    </el-form>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import {Edit} from "@element-plus/icons-vue"		//添加图标
const form = ref({
  name: ''
})
</script>

回到界面中就能看到输入框和图标啦🥳

自定义图标
  1. 我们导入准备好的图标资源文件进入项目的src文件夹当中

  2. src/components文件夹下新建Svgicon文件夹,再新建一个index.vue文件。

  3. 定义新建文件

    <template>
    <svg class="svg-icon" aria-hidden="true">
        <use :xlink:href="iconName"></use>
    </svg>
    </template>
    
    <script setup>
    import { defineProps, computed } from 'vue'
    // eslint-disable-next-line no-unused-vars
    const props = defineProps({
        icon: {
            type: String,
            required: true
        }
    })
    // eslint-disable-next-line no-unused-vars
    const iconName = computed(() => {
      return `#icon-${props.icon}`
    })
    </script>
    
    <style lang="scss" scoped>
    .svg-icon {
      width: 1em;
      height: 1em;
      vertical-align: -0.15em;
      fill: currentColor;
      overflow: hidden;
    }
    </style>
    
    • aria-hidden的值为"true"表示屏幕阅读器会将该元素对于可访问性的处理视为隐藏,不会将其读取给用户听。这通常用于隐藏纯装饰性的图像或其他元素,以避免干扰屏幕阅读器用户。
    • <use :xlink:href="icon"></use> 它是SVG的一个功能,用于引用其他SVG元素,实现图标的重用。
    • fill: currentColor;: 这个属性用于指定 SVG 图标的填充颜色。currentColor 表示使用当前元素的文本颜色作为填充颜色。因此,该图标的颜色将与其所在的父元素的文本颜色一致
  4. 使用webpack获取到文件夹所有的文件,相当于批量获取上面svg文件夹里的图标导入。所以我们再新建一个src/icons/下面新建一个文件index.js文件,导入以下👇代码

    import SvgIcon from '@/components/SvgIcon'
    
    const svgRequired = require.context('./svg',false,/\.svg$/)
    svgRequired.keys().forEach((item) => svgRequired(item))
    
    export default (app) => {
        app.component('svg-icon',SvgIcon)
    }
    
  5. main.js中导入

    import { createApp } from 'vue'
    import App from './App.vue'
    import router from './router'
    import store from './store'
    import '@/styles/index.scss'
    import SvgIcon from '@/icons'
    
    const app = createApp(App)
    SvgIcon(app)
    app.use(store).use(router).mount('#app')
    
  6. 在项目终端中安装svg-loader

    npm i --save-dev svg-sprite-loader@6.0.9
    
  7. 配置webpack,的vue.config.js粘贴以下代码:(完全粘贴我的就可以了,以免导致不同)

    const AutoImport = require('unplugin-auto-import/webpack')
    const Components = require('unplugin-vue-components/webpack')
    const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')
    
    const path = require('path')
    function resolve(dir) {
      return path.join(__dirname, dir)
    }
    const webpack = require('webpack')
    module.exports = {
      configureWebpack: config => {
        config.plugins.push(AutoImport({
          resolvers: [ElementPlusResolver()],
        }))
        config.plugins.push(Components({
          resolvers: [ElementPlusResolver()],
        }))
      },
      chainWebpack(config) {
        // 设置 svg-sprite-loader
        // config 为 webpack 配置对象
        // config.module 表示创建一个具名规则,以后用来修改规则
        config.module
          // 规则
          .rule('svg')
          // 忽略
          .exclude.add(resolve('src/icons'))
          // 结束
          .end()
        // config.module 表示创建一个具名规则,以后用来修改规则
        config.module
          // 规则
          .rule('icons')
          // 正则,解析 .svg 格式文件
          .test(/\.svg$/)
          // 解析的文件
          .include.add(resolve('src/icons'))
          // 结束
          .end()
          // 新增了一个解析的loader
          .use('svg-sprite-loader')
          // 具体的loader
          .loader('svg-sprite-loader')
          // loader 的配置
          .options({
            symbolId: 'icon-[name]'
          })
          // 结束
          .end()
        config
          .plugin('ignore')
          .use(
            new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn$/)
          )
        config.module
          .rule('icons')
          .test(/\.svg$/)
          .include.add(resolve('src/icons'))
          .end()
          .use('svg-sprite-loader')
          .loader('svg-sprite-loader')
          .options({
            symbolId: 'icon-[name]'
          })
          .end()
        }
    }
    

之后就是使用新建的组件,我们用下面的语句替换上面讲的添加图标内容:

<svg-icon icon="username" class="svg-container"></svg-icon>
<svg-icon icon="password" class="svg-container"></svg-icon>

<script setup>
import { ref } from 'vue'
// import { Edit } from '@element-plus/icons-vue' 还需要注释掉不用的edit
</script>

添加密码框

下面是添加密码框,做法也是和上面一样的,我们直接复制上面写好的图标和输入框代码

<!-- 下面是密码框 -->
      <el-form-item>
        <!-- 添加图标 -->
        <svg-icon icon="user" class="svg-container"></svg-icon>
        <el-input v-model="form.password"></el-input>
        <!-- 注意这里将绑定值改成密码password -->
      </el-form-item>
    
  <script setup>
    import { ref } from 'vue'
    import { Edit } from "@element-plus/icons-vue"
    const form = ref({
      username: '',
      password: ''  //注入password
    })
  </script>

添加按钮

<el-button type="primary" class="login-button">点击登录</el-button>

添加样式

注意:这个样式up没有带敲,所有大家就直接拿过来用吧(*´▽`)ノノ。

$bg: #2d3a4b;
$dark_gray: #889aa4;
$light_gray: #eee;
$cursor: #fff;

.login-container {
  min-height: 100%;
  width: 100%;
  background-color: $bg;
  overflow: hidden;

  .login-form {
    position: relative;
    width: 520px;
    max-width: 100%;
    padding: 160px 35px 0;
    margin: 0 auto;
    overflow: hidden;

    ::v-deep .el-form-item {
      border: 1px solid rgba(255, 255, 255, 0.1);
      background: rgba(0, 0, 0, 0.1);
      border-radius: 5px;
      color: #454545;
    }

    ::v-deep .el-input {
      display: inline-block;
      height: 47px;
      width: 85%;

      input {
        background: transparent;
        border: 0px;
        -webkit-appearance: none;
        border-radius: 0px;
        padding: 12px 5px 12px 15px;
        color: $light_gray;
        height: 47px;
        caret-color: $cursor;
      }
    }
    .login-button {
      width: 100%;
      box-sizing: border-box;
    }
  }

  .tips {
    font-size: 16px;
    line-height: 28px;
    color: #fff;
    margin-bottom: 10px;

    span {
      &:first-of-type {
        margin-right: 16px;
      }
    }
  }

  .svg-container {
    padding: 6px 5px 6px 15px;
    color: $dark_gray;
    vertical-align: middle;
    display: inline-block;
  }

  .title-container {
    position: relative;

    .title {
      font-size: 26px;
      color: $light_gray;
      margin: 0px auto 40px auto;
      text-align: center;
      font-weight: bold;
    }

    ::v-deep .lang-select {
      position: absolute;
      top: 4px;
      right: 0;
      background-color: white;
      font-size: 22px;
      padding: 4px;
      border-radius: 4px;
      cursor: pointer;
    }
  }

  .show-pwd {
    // position: absolute;
    // right: 10px;
    // top: 7px;
    font-size: 16px;
    color: $dark_gray;
    cursor: pointer;
    user-select: none;
  }
}

最后就实现了整个页面啦🥳

报错问题汇总

补充:如果在重启项目的时候报错,这个时候就需要重新安装一遍UI组件。

npm install --save element-plus

如果出现了以下问题:

  1. error '_' is defined but never used no-unused-vars

    • 在前面加一行注释:(表示忽略下一行校验)

      // eslint-disable-next-line
      
  2. error 'xxx' is assigned a value but never used

    • 在前面加一行注释:(通常表示你给一个变量赋了值,但在代码中没有使用它)

      // eslint-disable-next-line no-unused-vars
      
  3. error Newline required at end of file but not found eol-last

    • 这里有了格式冲突问题,最后应该加一行空行就行(最后想吐槽一下eslint要求太严格了😨)例如:
  4. Expected space or tab after '//' in comment.(spaced-comment)这个也一样是少了空格,就是在双斜杠//后面还要添加一个空格才行。

      例如:// 先空格,然后再接内容
    

实现登录功能

表单验证

Form 表单 | Element Plus (element-plus.org)转到表单验证一栏中,

这个rules就是使用规则,我们复制他并粘贴到<el-form>标签上,如下:

<el-form ref="formRef" :model="form" class="login-form" :rules="rules">

之后定义校验规则:

const rules = ref({
  username: [
    {
      // 必填项
      required: true,
      // 提示语
      message: 'Please input Activity name',
      // 触发条件方式
      trigger: 'blur'
    }
  ],
  password: [
  {
      required: true,
      message: 'Please input Activity name',
      trigger: 'blur'
    }
  ]
})

form-item标签上绑定检验规则:

<el-form-item prop="username">
<el-form-item prop="password">
实现统一校验

这里特别声明一下:校验规则不需要响应式,因为校验规则没有状态变化。所以我们只需要再添加一个点击事件,触发到登录按钮即可实现。

给按钮添加一个点击事件,并定义了一个handleLogin方法:

<el-button type="primary" class="login-button" @click="handleLogin">点击登录</el-button>

定义方法:

const formRef = ref(null)
const handleLogin = () => {
  formRef.value.validate((valid) => {
    if (valid) {
      alert('submit!')
    } else {
      console.log('error submit!!')
      return false
    }
  })
}

检验方法,打开我们的项目,点击登录按钮,如果弹出提示语就说明应用正确✔️了

登录请求

src下新建一个api文件夹然后再创建一个request.js文件。

  1. 导入axios

    import axios from "axios"

  2. 创建axios基础配置

    import axios from 'axios'
    // eslint-disable-next-line
    const service = axios.create({
    baseURL: process.env.VUE_APP_BASE_API,
    timeout: 5000
    })

    export default service

因为我们有开发环境和生产环境,所以我们要在根目录下面创建:开发环境.env.development和生产环境.env.production

//.env.development文件中添加代码
ENV = 'development'

VUE_APP_BASE_API = '/api'

//.env.production文件中添加代码
ENV = 'production'

VUE_APP_BASE_API = '/prod-api'

在vue.config.js配置代理来解决跨越问题

devServer: {
    https: false,
    hot: false,
    proxy: {
      '/api': {
        target: 'https://lianghj.top:8888/api/private/v1/',
        changeOrigin: true,
        pathRewrite: {
          '^/api': ''
        }
      }
    }
  }

在api文件夹中新建一个login.js文件用来发起post请求。

import request from './request'

export const login = (data) => {
  return request({
    url: '/login',
    method: 'POST',
    data
  })
}

回到登录页面,导入登录方法

import { login } from '@/api/login'

在登录校验方法中添加登录触发方法:

const formRef = ref(null)
const handleLogin = () => {
  formRef.value.validate(async (valid) => {
    if (valid) {
      // alert('submit!')
      await login(form.value)
    } else {
      console.log('error submit!!')
      return false
    }
  })
}
密码隐藏

ElementPlus 自带切换功能 <el-input type="password" show - password /> 即可

<el-input type="password" show-password/>

响应拦截器

响应拦截器是一种编程技术,通常在网络请求库中使用。它允许开发者在服务器响应返回给应用程序之前,对响应数据进行处理或修改。这可以用于日志记录、错误处理、数据验证、修改响应内容等目的。

例如,在JavaScript的Axios库中,可以通过配置响应拦截器来处理HTTP响应。这样,无论请求成功还是失败,都可以统一处理响应数据。

  1. 定义res接受数据

    const handleLogin = () => {
    formRef.value.validate(async (valid) => {
    if (valid) {
    // alert('submit!')
    const res = await login(form.value)// 添加一个res接受传递过来的数据
    console.log(res)// 反馈
    } else {
    console.log('error submit!!')
    return false
    }
    })
    }

  2. request.js文件添加响应请求拦截器

    service.interceptors.response.use(
      (response) => {
        const { data, meta } = response.data
        if (meta.status === 200 || meta.status === 201) {
          return data
        } else {
          ElMessage.error(meta.msg)
          return Promise.reject(new Error(meta.msg))
        }
      },
      (error) => {
        console.log(error.response)
        error.response && ElMessage.error(error.response.data)
        return Promise.reject(new Error(error.response.data))
      }
    )
    
    //request.js完整代码
    import axios from 'axios'
    import { ElMessage } from 'element-plus'
    import { diffTokenTime } from '@/utils/auth'
    import store from '@/store'
    const service = axios.create({
      baseURL: process.env.VUE_APP_BASE_API,
      timeout: 5000
    })
    
    service.interceptors.request.use(
      (config) => {
        if (localStorage.getItem('token')) {
          if (diffTokenTime()) {
            store.dispatch('app/logout')
            return Promise.reject(new Error('token 失效了'))
          }
        }
        config.headers.Authorization = localStorage.getItem('token')
        return config
      },
      (error) => {
        return Promise.reject(new Error(error))
      }
    )
    
    service.interceptors.response.use(
      (response) => {
        const { data, meta } = response.data
        if (meta.status === 200 || meta.status === 201) {
          return data
        } else {
          ElMessage.error(meta.msg)
          return Promise.reject(new Error(meta.msg))
        }
      },
      (error) => {
        console.log(error.response)
        error.response && ElMessage.error(error.response.data)
        return Promise.reject(new Error(error.response.data))
      }
    )
    export default service
    
  3. 改正报错样式

在我们密码错误的时候,报错的样式却不是我们意料当中的弹窗提醒.那是因为我们的UI组件库样式还没有导入.

将一下代码导入带到main.js当中:

import 'element-plus/dist/index.css'

这样密码错误样式就成功啦!!!

相关推荐
光影少年7 分钟前
vue2与vue3的全局通信插件,如何实现自定义的插件
前端·javascript·vue.js
As977_8 分钟前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习
susu108301891110 分钟前
vue3 css的样式如果background没有,如何覆盖有background的样式
前端·css
Ocean☾12 分钟前
前端基础-html-注册界面
前端·算法·html
Rattenking12 分钟前
React 源码学习01 ---- React.Children.map 的实现与应用
javascript·学习·react.js
Dragon Wu14 分钟前
前端 Canvas 绘画 总结
前端
CodeToGym18 分钟前
Webpack性能优化指南:从构建到部署的全方位策略
前端·webpack·性能优化
~甲壳虫20 分钟前
说说webpack中常见的Loader?解决了什么问题?
前端·webpack·node.js
~甲壳虫23 分钟前
说说webpack proxy工作原理?为什么能解决跨域
前端·webpack·node.js
Cwhat25 分钟前
前端性能优化2
前端