使用 Vue3、Node.js、MySQL、Electron 和 Express 实现用户登录、文章管理和截屏功能
在现代 Web 开发中,前后端分离的架构已经成为主流。本文将详细介绍如何使用 Vue3、Node.js、MySQL、Electron 和 Express 实现一个完整的用户登录、文章管理和截屏功能的应用。我们将从项目的初始化开始,逐步实现各个功能模块,并提供详细的代码示例。
项目初始化
前端:Vue3
首先,我们使用 Vue CLI 创建一个新的 Vue3 项目:
npm install -g @vue/cli
vue create vue-electron-app
cd vue-electron-app
选择默认配置或根据需要进行自定义配置。
后端:Node.js 和 Express
在项目根目录下创建一个新的文件夹 server,并在其中初始化一个新的 Node.js 项目:
mkdir server
cd server
npm init -y
npm install express mysql body-parser cors
创建 server.js 文件并设置基本的 Express 服务器:
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
const port = 3000;app.use(cors());
app.use(bodyParser.json());app.listen(port, () => {console.log(`Server running on port ${port}`);
});
数据库:MySQL
创建一个新的 MySQL 数据库和表:
CREATE DATABASE vue_electron_app;USE vue_electron_app;CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(255) NOT NULL,password VARCHAR(255) NOT NULL
);CREATE TABLE articles (id INT AUTO_INCREMENT PRIMARY KEY,title VARCHAR(255) NOT NULL,content TEXT NOT NULL,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
实现用户登录功能
后端:用户登录 API
在 server 文件夹中创建一个新的文件 auth.js,并实现用户注册和登录功能:
const express = require('express');
const router = express.Router();
const mysql = require('mysql');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');const db = mysql.createConnection({host: 'localhost',user: 'root',password: 'password',database: 'vue_electron_app'
});router.post('/register', (req, res) => {const { username, password } = req.body;const hashedPassword = bcrypt.hashSync(password, 10);db.query('INSERT INTO users (username, password) VALUES (?, ?)', [username, hashedPassword], (err, result) => {if (err) return res.status(500).send(err);res.status(201).send('User registered');});
});router.post('/login', (req, res) => {const { username, password } = req.body;db.query('SELECT * FROM users WHERE username = ?', [username], (err, results) => {if (err) return res.status(500).send(err);if (results.length === 0) return res.status(404).send('User not found');const user = results[0];const isPasswordValid = bcrypt.compareSync(password, user.password);if (!isPasswordValid) return res.status(401).send('Invalid password');const token = jwt.sign({ id: user.id }, 'secret_key', { expiresIn: '1h' });res.status(200).send({ token });});
});module.exports = router;
在 server.js 中引入并使用该路由:
const authRoutes = require('./auth');
app.use('/auth', authRoutes);
前端:用户登录页面
在 Vue 项目中创建一个新的组件 Login.vue:
<template><div><h2>Login</h2><form @submit.prevent="login"><div><label for="username">Username:</label><input type="text" v-model="username" required /></div><div><label for="password">Password:</label><input type="password" v-model="password" required /></div><button type="submit">Login</button></form></div>
</template><script>
import axios from 'axios';export default {data() {return {username: '',password: ''};},methods: {async login() {try {const response = await axios.post('http://localhost:3000/auth/login', {username: this.username,password: this.password});localStorage.setItem('token', response.data.token);this.$router.push('/dashboard');} catch (error) {console.error('Login failed:', error);}}}
};
</script>
实现文章管理功能
后端:文章管理 API
在 server 文件夹中创建一个新的文件 articles.js,并实现文章的 CRUD 操作:
const express = require('express');
const router = express.Router();
const mysql = require('mysql');
const jwt = require('jsonwebtoken');const db = mysql.createConnection({host: 'localhost',user: 'root',password: 'password',database: 'vue_electron_app'
});const authenticate = (req, res, next) => {const token = req.headers['authorization'];if (!token) return res.status(401).send('Access denied');jwt.verify(token, 'secret_key', (err, decoded) => {if (err) return res.status(401).send('Invalid token');req.userId = decoded.id;next();});
};router.post('/articles', authenticate, (req, res) => {const { title, content } = req.body;db.query('INSERT INTO articles (title, content) VALUES (?, ?)', [title, content], (err, result) => {if (err) return res.status(500).send(err);res.status(201).send('Article created');});
});router.get('/articles', authenticate, (req, res) => {db.query('SELECT * FROM articles', (err, results) => {if (err) return res.status(500).send(err);res.status(200).send(results);});
});router.put('/articles/:id', authenticate, (req, res) => {const { id } = req.params;const { title, content } = req.body;db.query('UPDATE articles SET title = ?, content = ? WHERE id = ?', [title, content, id], (err, result) => {if (err) return res.status(500).send(err);res.status(200).send('Article updated');});
});router.delete('/articles/:id', authenticate, (req, res) => {const { id } = req.params;db.query('DELETE FROM articles WHERE id = ?', [id], (err, result) => {if (err) return res.status(500).send(err);res.status(200).send('Article deleted');});
});module.exports = router;
在 server.js 中引入并使用该路由:
const articleRoutes = require('./articles');
app.use('/api', articleRoutes);
前端:文章管理页面
在 Vue 项目中创建一个新的组件 ArticleManager.vue:
<template><div><h2>Article Manager</h2><form @submit.prevent="createArticle"><div><label for="title">Title:</label><input type="text" v-model="title" required /></div><div><label for="content">Content:</label><textarea v-model="content" required></textarea></div><button type="submit">Create Article</button></form><ul><li v-for="article in articles" :key="article.id"><h3>{{ article.title }}</h3><p>{{ article.content }}</p><button @click="deleteArticle(article.id)">Delete</button><button @click="editArticle(article)">Edit</button></li></ul></div>
</template><script>
import axios from 'axios';export default {data() {return {title: '',content: '',articles: []};},async created() {await this.fetchArticles();},methods: {async fetchArticles() {try {const response = await axios.get('http://localhost:3000/api/articles', {headers: { Authorization: localStorage.getItem('token') }});this.articles = response.data;} catch (error) {console.error('Failed to fetch articles:', error);}},async createArticle() {try {await axios.post('http://localhost:3000/api/articles', {title: this.title,content: this.content}, {headers: { Authorization: localStorage.getItem('token') }});this.title = '';this.content = '';await this.fetchArticles();} catch (error) {console.error('Failed to create article:', error);}},async deleteArticle(id) {try {await axios.delete(`http://localhost:3000/api/articles/${id}`, {headers: { Authorization: localStorage.getItem('token') }});await this.fetchArticles();} catch (error) {console.error('Failed to delete article:', error);}},editArticle(article) {this.title = article.title;this.content = article.content;// Implement update logic here}}
};
</script>
实现截屏功能
Electron:截屏功能
在项目根目录下安装 Electron:
npm install electron --save-dev
创建 main.js 文件并配置 Electron 主进程:
const { app, BrowserWindow, ipcMain, desktopCapturer } = require('electron');
const path = require('path');function createWindow() {const win = new BrowserWindow({width: 800,height: 600,webPreferences: {preload: path.join(__dirname, 'preload.js'),contextIsolation: true,enableRemoteModule: false,nodeIntegration: false}});win.loadURL('http://localhost:8080');
}app.whenReady().then(createWindow);app.on('window-all-closed', () => {if (process.platform !== 'darwin') {app.quit();}
});app.on('activate', () => {if (BrowserWindow.getAllWindows().length === 0) {createWindow();}
});ipcMain.handle('capture-screen', async () => {const sources = await desktopCapturer.getSources({ types: ['screen'] });return sources[0].thumbnail.toDataURL();
});
创建 preload.js 文件并配置预加载脚本:
const { contextBridge, ipcRenderer } = require('electron');contextBridge.exposeInMainWorld('electron', {captureScreen: () => ipcRenderer.invoke('capture-screen')
});
前端:截屏功能页面
在 Vue 项目中创建一个新的组件 ScreenCapture.vue:
<template><div><h2>Screen Capture</h2><button @click="captureScreen">Capture Screen</button><img v-if="screenshot" :src="screenshot" alt="Screenshot" /></div>
</template><script>
export default {data() {return {screenshot: null};},methods: {async captureScreen() {try {this.screenshot = await window.electron.captureScreen();} catch (error) {console.error('Failed to capture screen:', error);}}}
};
</script>
结语
通过本文,我们详细介绍了如何使用 Vue3、Node.js、MySQL、Electron 和 Express 实现一个完整的用户登录、文章管理和截屏功能的应用。希望这篇文章能为你提供有价值的参考,帮助你更好地理解和实现前后端分离的应用开发。
如果你有任何问题或建议,欢迎在评论区留言讨论。Happy coding!
相关文章:
使用 Vue3、Node.js、MySQL、Electron 和 Express 实现用户登录、文章管理和截屏功能
在现代 Web 开发中,前后端分离的架构已经成为主流。本文将详细介绍如何使用 Vue3、Node.js、MySQL、Electron 和 Express 实现一个完整的用户登录、文章管理和截屏功能的应用。我们将从项目的初始化开始,逐步实现各个功能模块,并提供详细的代…...
django中日志模块logging的配置和使用
一、文件的配置 settings.py文件中添加LOGGING块的配置,配置如下 # 日志记录 LOGGING {"version": 1,"disable_existing_loggers": False, # 用于确定在应用新的日志配置时是否禁用之前配置的日志器# 格式器"formatters": {"v…...
pyqt/pyside QTableWidget失去焦点后,选中的行仍高亮的显示
正常情况下pyqt/pyside的QTableWidget,点击input或者按钮失去焦点后 行的颜色消失了 如何在失去焦点时保持行的选中颜色,增加下面的代码: # 获取当前表格部件的调色板 p tableWidget.palette()# 获取活跃状态下的高亮颜色和高亮文本颜色&a…...
函数定义、合约与面向对象(以太坊solidity合约)
函数定义、合约与面向对象(以太坊solidity合约) 1-函数定义、构造与多态2-事件日志3-面向对象特征 1-函数定义、构造与多态 创建合约就是创建类,部署合约就是实例化 合约的方法还支持多态 还能使用第三方的库进行开发 整个合约部署后&…...
微服务:nacos
Nacos 由Alibaba推出的集成于SpringCloudAlibaba中的一款开源注册中心框架 主要功能: 注册中心 配置管理 nacos的安装和部署 nacos默认访问端口8848 docker pull nacos/nacos-server:1.2.0 docker run --env MODEstandalone --name nacos --restartalways -d -p 8848:8…...
前端css常用笔记
文章目录 一、样式二、vue笔记2.1、组件之间的通信2.1.1 子组件调用父组件的方法2.1.2 父组件调用子组件的方法2.1.3 孙组件调用祖父组件方法的实现 2.2、使用若依时,node_nodules越来越大的问题2.3、echart笔记 一、样式 1 文字与图标对不齐的解决方法 /**给icon加上这个样式即…...
WINUI或WPF灵活使用样式、控件模板、自定义控件、用户控件
在WINUI与WPF 中,控件模板(ControlTemplate)、样式(Style)、自定义控件(CustomControl)和用户控件(UserControl)都是构建复杂和灵活用户界面的重要工具,但它们…...
如何用EXCEL自动解方程/方程组?利用 矩阵乘法X=A-*B,X=mmult(minverse(A), B)
目录 问题的由来 1 数据 → 模拟分析 → 单变量求解 1.1 找一个单元格填入公式 1.2 功能入口 1.3 选择单变量求解,分别填入内容 1.4 求解 1.5 这个感觉用处不大 2 重点介绍,用EXCEL进行矩阵运算解方程的操作 2.1 运用EXCEL进行矩阵运算&…...
ComfyUI进阶:Comfyroll插件 (二)
前言: 学习ComfyUI是一场持久战,而Comfyroll Studio 是一款功能强大的自定义节点集合,专为 ComfyUI 用户打造,旨在提供更加丰富和专业的图像生成与编辑工具。借助这些节点,用户可以在静态图像的精细调整和动态动画的复…...
Spring Boot集成Activity7实现简单的审批流
由于客户对于系统里的一些新增数据,例如照片墙、照片等,想实现上级逐级审批通过才可见的效果,于是引入了Acitivity7工作流技术来实现,本文是对实现过程的介绍讲解,由于我是中途交接前同事的这块需求,所以具…...
自动驾驶,革了谁的命
概述 从AI 的出现开始,到现在已经慢慢地开始改变着周遭的世界。 从对话聊天,到当前的看图识文,图片转动效等等,慢慢地在与实体结合后,其发挥的威力是巨大的。 科技将会是改变世界的核心驱动力之一,已经深…...
在线实习项目|泰迪智能科技企业级项目学习,暑期大数据人工智能学习
在线实习介绍 实习时间:每个项目周期七周左右 面向对象:大数据、计算机相关专业学生;大三、大四毕业年度学生 在线实习收获 1、获得项目实战技能,积累项目经验 2、获得在线实习证明 项目特点…...
【BUG】已解决:To update, run: python.exe -m pip install --upgrade pip
To update, run: python.exe -m pip install --upgrade pip 目录 To update, run: python.exe -m pip install --upgrade pip 【常见模块错误】 解决办法: 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英杰&…...
Lua 运算符
Lua 运算符 Lua 是一种轻量级的编程语言,广泛用于游戏开发、脚本编写和其他应用程序。它具有一套丰富的运算符,用于执行各种数学和逻辑操作。本文将详细介绍 Lua 中的运算符,包括算术运算符、关系运算符、逻辑运算符和其他特殊运算符。 算术…...
园区道路车辆智能管控视频解决方案,打造安全畅通的园区交通环境
一、背景需求分析 随着企业园区的快速发展和扩张,道路车辆管理成为了保障园区秩序、提升运营效率及确保员工安全的重要任务。针对这一需求,旭帆科技TSINGSEE青犀提出了一种企业园区道路车辆管控的解决方案,通过整合视频监控、智能识别等技术…...
MATLAB R2023b下载安装教程汉化中文版设置
MATLAB R2023b下载安装教程汉化中文版设置 Matlab 是一款功能强大的商业数学软件 Matlab(Matrix Labortory)即矩阵实验室,它在数值计算、数据分析、算法开发、建模与仿真等众多领域都发挥着重要作用。 Matlab 具有以下显著特点和优势&…...
Java二十三种设计模式-工厂方法模式(2/23)
工厂方法模式:设计模式中的瑞士军刀 引言 在软件开发中,工厂方法模式是一种常用的创建型设计模式,它用于处理对象的创建,将对象的实例化推迟到子类中进行。这种模式不仅简化了对象的创建过程,还提高了代码的可维护性…...
【iOS】OC类与对象的本质分析
目录 前言clang常用命令对象本质探索属性的本质对象的内存大小isa 指针探究 前言 OC 代码的底层实现都是 C/C代码,OC 的对象都是基于 C/C 的数据结构实现的,实际 OC 对象的本质就是结构体,那到底是一个怎样的结构体呢? clang常用…...
【机器学习】使用Python的dlib库实现人脸识别技术
🔥 个人主页:空白诗 文章目录 一、引言二、传统人脸识别技术1. 基于几何特征的方法2. 基于模板匹配的方法3. 基于统计学习的方法 三、深度学习在脸识别中的应用1. 卷积神经网络(CNN)2. FaceNet和ArcFace 四、使用Python和dlib库实…...
GitHub 令牌泄漏, Python 核心资源库面临潜在攻击
TheHackerNews网站消息,软件供应链安全公司 JFrog 的网络安全研究人员称,他们发现了一个意外泄露的 GitHub 令牌,可授予 Python 语言 GitHub 存储库、Python 软件包索引(PyPI)和 Python 软件基金会(PSF&…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
