07-封装登录接口

src 目录下面新建 api/request.ts

ts 复制代码
import axios from 'axios'

// 创建 axios 实例
const request = axios.create({
    baseURL: '/api', // 基础路径
    timeout: 15000, // 请求超时时间
})

// 请求拦截器
request.interceptors.request.use(
    (config) => {
        return config
    },
    (error) => {
        return Promise.reject(error)
    }
)

// 响应拦截器
request.interceptors.response.use(
    (response) => {
        return response.data
    },
    (error) => {
        return Promise.reject(error)
    }
)

export default request

在 api 文件夹下面在添加 login.ts

ts 复制代码
import request from './request'

// 登录接口返回token
export const adminLoginApi = (data: unknown) => {
    return request.post('/admin/login', data)
}

然后在登录页面点击登录的时候调用该登录接口

html 复制代码
<template>
    <div class="login-rule-form">
        <div class="content">
            <div class="title">商品管理系统</div>
            <el-form ref="ruleFormRef" :model="ruleForm" status-icon :rules="rules" label-width="60px">
                <el-form-item prop="username" label="账号">
                    <el-input v-model="ruleForm.username" type="text" placeholder="请输入账号"/>
                </el-form-item>
                <el-form-item prop="pwd" label="密码">
                    <el-input v-model="ruleForm.pwd" type="password" placeholder="请输入密码"/>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="loginFn()">登录</el-button>
                </el-form-item>
            </el-form>
        </div>
    </div>
</template>

<script lang='ts' setup>
import { onMounted, reactive, ref } from 'vue'
import { adminLoginApi } from '@/api/login'

let ruleForm = reactive({
    username: "",
    pwd: ""
})
// 自定义密码校验规则(_variable - 未使用的变量 ts不校验)
const validatePwd = (_rule: unknown, value: string | undefined, callback: (msg?: string) => void) => {
    if(!value) {
        callback('密码不能为空')
    } else {
        callback()
    }
}
// 校验规则
let rules = reactive({
    username: [
        {
            required: true,
            message: '用户名不能为空',
            trigger: 'blur'
        }
    ],
    pwd: [
        {
            required: true,
            validator: validatePwd,
            trigger: 'blur'
        }
    ]
})

// 获取el-form组件对象
let ruleFormRef = ref()

onMounted(() => {
    console.log('组件实例:', ruleFormRef.value)
    console.log('DOM 元素:', ruleFormRef.value?.$el)
})

// 登录
const loginFn = () => {
    ruleFormRef.value.validate().then(() => {
        adminLoginApi({
            username: ruleForm.username,
            password: ruleForm.pwd
        }).then((res) => {
            console.log(res)
        })
    }).catch(() => {
        console.log('校验不通过')
    })
}

</script>

<style lang='less' scoped>
.login-rule-form {
    width: 100%;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: #f5f5f5;
    overflow: hidden;
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    .content {
        width: 420px;
        padding: 40px;
        background-color: #fff;
        border-radius: 8px;
        box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
        box-sizing: border-box;
        .title {
            font-size: 28px;
            font-weight: bold;
            text-align: center;
            margin-bottom: 30px;
        }
    }

    :deep(.el-form) {
        .el-form-item {
            margin-bottom: 20px;
            &:last-child {
                margin-bottom: 0;
            }
        }
        .el-button {
            width: 100%;
        }
    }
}
</style>

此外需要配置一下 @ 符号

vite.config.ts 配置

ts 复制代码
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import path from 'path'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'),
    },
  },
})

tsconfig.app.json 配置

json 复制代码
{
  "extends": "@vue/tsconfig/tsconfig.dom.json",
  "compilerOptions": {
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "types": ["vite/client"],
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    },

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "erasableSyntaxOnly": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedSideEffectImports": true
  },
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
}

点击登录我们就可以看到接口报 404 了

相关推荐
Irene19914 小时前
Vue3 TypeScript 项目中,Emits 验证的使用场景
typescript·vue3·验证
箫笙默11 小时前
Vue3基础笔记
笔记·vue·vue3
Sapphire~15 小时前
Vue3-09 创建响应式数据(基本类型ref和对象类型reactive)
vue3
Sapphire~19 小时前
Vue3-02 脚手架创建项目及文件解释作用
vue3
Cherry的跨界思维2 天前
28、AI测试环境搭建与全栈工具实战:从本地到云平台的完整指南
java·人工智能·vue3·ai测试·ai全栈·测试全栈·ai测试全栈
Cherry的跨界思维4 天前
【AI测试全栈:Vue核心】22、从零到一:Vue3+ECharts构建企业级AI测试可视化仪表盘项目实战
vue.js·人工智能·echarts·vue3·ai全栈·测试全栈·ai测试全栈
前端小L4 天前
专题三:完善响应式 —— readonly 与 isReactive
源码·vue3
神色自若4 天前
vue3 带tabs的后台管理系统,切换tab标签后,共用界面带参数缓存界面状态
前端·vue3
前端小L5 天前
专题一:搭建测试驱动环境 (TypeScript + Vitest)
前端·javascript·typescript·源码·vue3
前端小L5 天前
专题二:核心机制 —— reactive 与 effect
javascript·源码·vue3