Vue3+node.js实现登录

news2024/11/29 19:03:21

文章目录

    • 前端代码实现
    • 后端代码实现
      • 跨域处理

前端代码实现

效果图
在这里插入图片描述
前端代码实现

<template>
    <div class="login-container">
        <el-card class="login-card">
            <template #header>
                <div class="card-header">
                    <span>登录</span>
                </div>
            </template>
            <el-form label-width="80px" ref="formRef" :model="formData" :rules="rules">
                <el-form-item label="用户名" prop="username">
                    <el-input v-model="formData.username" placeholder="请输入用户名" ></el-input>
                </el-form-item>
                <el-form-item label="密码"  prop="password">
                    <el-input v-model="formData.password" type="password" placeholder="请输入密码"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-button style="width: 100%;"  @click="handleSubmit"  type="primary">登录</el-button>
                </el-form-item>
                <el-form-item >
                    <el-button link type="info" @click="toggleToLogin"  >没有账号?去注册</el-button>
                </el-form-item>
            </el-form>
        </el-card>
    </div>
  </template>
  
  
  <script setup>
  import { ElMessage } from 'element-plus';
  import axios from 'axios';
  import { reactive, ref } from 'vue';
  
  //初始化
  const formRef = ref(null)
  //跳转注册页面
  const toggleToLogin = () => {
  location.href = '/register'
  }
  //表单数据
  const formData = ref({
    username:'',
    password:''
  }) 
// 修正校验规则
const rules = reactive({
    username:[
        {required: true, message: '请输入用户名', trigger: 'blur'},
        {min: 3, max: 20, message: '长度3到20个字符', trigger: 'blur'} 
    ],
    password:[
        {required: true, message: '请输入密码', trigger: 'blur'},
        {min: 3, max: 20, message: '长度在3到20个字符', trigger: 'blur'}
    ]
})

// 登录处理
const handleSubmit = async () => {
    const form = formRef.value
    if(!form) return;
    try {
      await form.validate();
      const res = await axios.post('http://localhost:3030/user/login', formData.value);
      
      if(res.data.code === 200) {  
        ElMessage.success( '登录成功');
        
        location.href = '/manager/home';
      } else {
        ElMessage.error( '登录失败');
      }
    } catch (error) {
      console.error('登录请求错误', error);
      ElMessage.error(error.response?.data?.message || '登录失败,请稍后重试');
    }
}
  </script>
  
  
  <style scoped>
  .login-container {
    min-height: 100vh;
    display: flex;
    background-color: aqua;
    align-items: center;
    justify-content: center;
  }
  .login-card {
    width: 400px;
    border-radius: 8px;
  }
  .card-header {
    font-size: 24px;
    font-weight: bold;
    text-align: center;
  }
  
  </style>

后端代码实现

创建文件夹router,在router目录下创建path.js文件

//登录
router.post('/login', async (req,res)=>{
    try {
        const {username, password} = req.body
        
        // 验证参数
        if(!username?.trim() || !password?.trim()){  // 增加trim()检查
            return res.status(400).json({
                code: 400,
                message: '用户名和密码不能为空'
            })
        }

        const sql = 'select * from user where username = ? limit 1'
        const [rows] = await pool.query(sql,[username])
        
        if(rows.length === 0){
            return res.status(401).json({
                code: 401,
                message: '用户名或密码错误'  
            })
        }

        const user = rows[0]
        if(user.password !== password){
            return res.status(401).json({
                code: 401,
                message: '用户名或密码错误'
            })
        } 

        // 删除敏感信息
        delete user.password
        
        success(res, {
            code: 200,
            user,
            message: '登录成功'
        })
    } catch (error) {
        handleError(res, error)
    }
})

跨域处理

前端跨域,在vite.config.js中添加跨域请求

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    vueDevTools(),
  ],
  server:{
    proxy:{
      '/api':{target:'http://localhost:3030',changeOrigin:true,
        rewrite:(path) => path.replace(/^\/api/,'')
      }
    }
  },
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    },
  },
})

后端跨域,创建app.js,导入路由

const express = require('express')
const cors = require('cors')
const router = require('./router/path')


const app = express()

//解析数据
app.use(express.json())
app.use(express.urlencoded({extended:true}))
//跨域处理
app.use(cors(
    {
        origin:['http://localhost:5173'],
        methods:['GET','POST','PUT','DELETE'],
        credentials:true,
        allowedHeaders:['Content-Type']
    }
))

app.use('/user',router)

const PORT = process.env.PORT || 3030
app.listen(PORT,()=>{
    console.log(`服务正在运行...端口为${PORT}`)
})

实现注册界面

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2249933.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络原理(一)—— http

什么是 http http 是一个应用层协议&#xff0c;全称为“超文本传输协议”。 http 自 1991 年诞生&#xff0c;目前已经发展为最主流使用的一种应用层协议。 HTTP 往往基于传输层的 TCP 协议实现的&#xff0c;例如 http1.0&#xff0c;http1.0&#xff0c;http2.0 http3 是…

Next.js-样式处理

#题引&#xff1a;我认为跟着官方文档学习不会走歪路 Next.js 支持多种为应用程序添加样式的方法&#xff0c;包括&#xff1a; CSS Modules&#xff1a;创建局部作用域的 CSS 类&#xff0c;避免命名冲突并提高可维护性。全局 CSS&#xff1a;使用简单&#xff0c;对于有传统…

navicat premium连接sqlserver

连接不上就双击安装图中的msi文件之后再连试试&#xff01;

Axure RP教程:创建高效用户界面和交互

Axure RP是一款广受好评的软件&#xff0c;专门用于设计精致的用户界面和交互体验。这款软件提供了众多UI控件&#xff0c;并根据它们的用途进行了分类。与此同时&#xff0c;国产的即时设计软件作为Axure的替代品&#xff0c;支持在线协作和直接在浏览器中使用&#xff0c;无需…

Qt导出Excel图表

目的 就是利用Qt导出Excel图表,如果直接画Excel 图表&#xff0c;比较麻烦些&#xff0c;代码写得也复杂了&#xff1b;而直接利用Excel模块就简单了&#xff0c;图表在模块当中已经是现成的了&#xff0c;Qt程序只更改数据就可以了&#xff0c;这篇文章就是记录一下利用模块上…

DeSTSeg: Segmentation Guided Denoising Student-Teacher for Anomaly Detection

DeSTSeg: Segmentation Guided Denoising Student-Teacher for Anomaly Detection 清华、苹果 个人感觉 Introduction 很自然的让读者理解作者问题的提出&#xff0c;也有例子直接证明了这个问题的存在&#xff0c;值得借鉴&#xff01;&#xff01; Related work写的也很不…

Java设计模式 —— 【创建型模式】工厂模式(简单工厂、工厂方法模式、抽象工厂)详解

文章目录 前言一、简单工厂&#xff08;静态工厂&#xff09;1、概述2、代码实现3、优缺点 二、工厂方法模式1、概述2、代码实现3、优缺点 三、抽象工厂模式1、概述2、代码实现3、优缺点 四、总结 前言 先看个案例&#xff1a;【手机和手机店】在没有工厂的时候&#xff0c;手…

利用Java爬虫获取阿里巴巴中国站跨境属性的详细指南

在全球化贸易的浪潮中&#xff0c;跨境电商正成为连接全球买家和卖家的重要桥梁。阿里巴巴中国站作为全球领先的B2B电子商务平台&#xff0c;提供了海量的商品信息&#xff0c;其中跨境属性信息对于跨境电商尤为重要。本文将详细介绍如何使用Java编写爬虫&#xff0c;从阿里巴巴…

「Qt Widget中文示例指南」如何为窗口实现流程布局?(二)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 本文将展示如何为不…

鸿蒙学习使用模拟器运行应用(开发篇)

文章目录 1、系统类型和运行环境要求2、创建模拟器3、启动和关闭模拟器4、安装应用程序包和上传文件QA:在Windows电脑上启动模拟器&#xff0c;提示未开启Hyper-V 1、系统类型和运行环境要求 Windows 10 企业版、专业版或教育版及以上&#xff0c;且操作系统版本不低于10.0.18…

Java后端如何进行文件上传和下载 —— 本地版

简介&#xff1a; 本文详细介绍了在Java后端进行文件上传和下载的实现方法&#xff0c;包括文件上传保存到本地的完整流程、文件下载的代码实现&#xff0c;以及如何处理文件预览、下载大小限制和运行失败的问题&#xff0c;并提供了完整的代码示例。 大体思路 1、文件上传 …

SqlServer强制转换函数TRY_CONVERT和TRY_CAST

SqlServer强制转换函数TRY_CONVERT和TRY_CAST的介绍和案例分享 1、本节内容 CAST 和 CONVERT TRY_CAST TRY_CONVERT 适用于&#xff1a; SQL ServerAzure SQL 数据库Azure SQL 托管实例Azure Synapse Analytics 分析平台系统 (PDW)Microsoft Fabric 中的 SQL 分析端点Micro…

透视投影(Perspective projection)与等距圆柱投影(Equirectangular projection)

一、透视投影 1.方法概述 Perspective projection&#xff08;透视投影&#xff09;是一种模拟人眼观察三维空间物体时的视觉效果的投影方法。它通过模拟观察者从一个特定视点观察三维场景的方式来创建二维图像。在透视投影中&#xff0c;远处的物体看起来比近处的物体小&…

linux 中后端jar包启动不起来怎么回事 -bash: java: 未找到命令

一、用以下命令检查jdk版本 输入&#xff1a;java -version&#xff0c;如果JDK 环境变量没有配置&#xff0c;你会看到如下提示 二、配置jdk环境 1.先找到/etc/profile文件&#xff0c;然后在该文件最后面加上以下配置 export JAVA_HOME/usr/local/jdk-21.0.1 export PATH$…

TDengine在debian安装

参考官网文档&#xff1a; 官网安装文档链接 从列表中下载获得 Deb 安装包&#xff1b; TDengine-server-3.3.4.3-Linux-x64.deb (61 M) 进入到安装包所在目录&#xff0c;执行如下的安装命令&#xff1a; sudo dpkg -i TDengine-server-<version>-Linux-x64.debNOTE 当…

Java开发工程师最新面试题库系列——Java基础部分(附答案)

如果你有更好的想法请在评论区留下您的答案&#xff0c;一起交流讨论# 面向对象有哪些特征&#xff1f; 答&#xff1a;继承、封装、多态 JDK与JRE的区别是什么&#xff1f; 答&#xff1a;JDK是java开发时所需环境&#xff0c;它包含了Java开发时需要用到的API&#xff0c;JRE…

linux系统下如何将xz及ISO\img等格式压缩包(系统)烧写到优盘(TF卡)

最近用树莓派做了个NAS&#xff0c;效果一般&#xff0c;缺少监控及UI等&#xff0c;详细见这篇文章&#xff1a; https://blog.csdn.net/bugsycrack/article/details/135344782?spm1001.2014.3001.5501 所以下载了专门的基于树莓派的NAS系统直接使用。这篇文章是顺便复习一…

计算机的错误计算(一百六十八)

摘要 算式“(5^25*(1/25)^(1/5)*3^25(1/25)^(1/5)*5^25*3^(251/5)-(9/25)^(1/5)*3^25*5^25-(1/25)^(1/5)*3^25*5.0^25*(13^(1/5)-3^(2/5.0)))”的值为0。但是&#xff0c;在 MATLAB 中计算它&#xff0c;则输出含有15位整数。 例1. 计算 直接贴图吧&#xff1a; 这样&#x…

Python学习------第十四天

匿名函数 1.函数作为参数来传递 &#xff08;函数的参数中调用另外一个函数&#xff09; #定义一个函数&#xff0c;接受另一个函数作为参数传入 #计算逻辑的传入 def test_func(compute):result compute(1,2)print(result)print(f"{type(result)}")print(f"…

【经典论文阅读】Transformer(多头注意力 编码器-解码器)

Transformer attention is all you need 摘要 完全舍弃循环 recurrence 和卷积 convolutions 只依赖于attention mechanisms 【1】Introduction 完全通过注意力机制&#xff0c;draw global dependencies between input and output 【2】Background 1&#xff1a;self-…