如何用Vue3 + NodeMailer + TypeScript结合SMTP服务器实现邮件发送?
Vue3 + TypeScript 切换 NodeMailer 实现邮件发送示例
注意:NodeMailer 不能直接在浏览器端运行(会泄露邮箱账号/授权码),必须通过后端接口转发请求
1. 搭建后端接口(Node.js + Express + NodeMailer)
先初始化后端项目,安装依赖:
npm init -y npm install express nodemailer cors
创建server.js文件:
const express = require('express'); const nodemailer = require('nodemailer'); const cors = require('cors'); const app = express(); app.use(cors()); // 处理跨域 app.use(express.json()); // 解析JSON请求体 // 配置SMTP transporter(替换成你的邮箱信息) const transporter = nodemailer.createTransport({ host: 'smtp.qq.com', // 其他邮箱请替换对应SMTP地址,比如Gmail用smtp.gmail.com port: 465, secure: true, auth: { user: 'your-email@qq.com', // 你的邮箱账号 pass: 'your-authorization-code' // 邮箱SMTP授权码(不是登录密码) } }); // 邮件发送接口 app.post('/send-email', async (req, res) => { try { const { to, subject, text } = req.body; await transporter.sendMail({ from: '"你的网站名称" <your-email@qq.com>', // 发件人显示信息 to, // 收件人邮箱 subject, // 邮件标题 text // 邮件内容 }); res.status(200).json({ success: true, message: '邮件发送成功' }); } catch (error) { console.error(error); res.status(500).json({ success: false, message: '邮件发送失败' }); } }); app.listen(3000, () => { console.log('后端服务运行在 http://localhost:3000'); });
启动后端:
node server.js
2. 前端Vue3 + TypeScript 代码示例
假设你的Vue组件模板已包含提交按钮,脚本部分如下:
<template> <!-- 你的现有模板,可保留原有的输入框布局 --> <div class="email-form"> <input v-model="form.to" placeholder="收件人邮箱" type="email" /> <input v-model="form.subject" placeholder="邮件标题" /> <textarea v-model="form.text" placeholder="邮件内容" rows="5"></textarea> <button @click="handleSendEmail" :disabled="isSending"> {{ isSending ? '发送中...' : '发送邮件' }} </button> <div class="message" :class="{ success: isSuccess, error: !isSuccess }" v-if="message"> {{ message }} </div> </div> </template> <script setup lang="ts"> import axios from 'axios'; import { ref } from 'vue'; // 表单数据 const form = ref({ to: '', subject: '', text: '' }); const message = ref(''); const isSending = ref(false); const isSuccess = ref(false); // 发送邮件处理函数 const handleSendEmail = async () => { // 表单校验 if (!form.value.to.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/) || !form.value.subject || !form.value.text) { message.value = '请填写有效的邮箱及完整内容'; isSuccess.value = false; return; } isSending.value = true; try { const response = await axios.post('http://localhost:3000/send-email', form.value); message.value = response.data.message; isSuccess.value = true; // 清空表单 form.value = { to: '', subject: '', text: '' }; } catch (error) { message.value = '发送失败,请稍后重试'; isSuccess.value = false; console.error(error); } finally { isSending.value = false; } }; </script> <style scoped> .email-form { display: flex; flex-direction: column; gap: 10px; max-width: 400px; margin: 20px; } input, textarea { padding: 8px; border: 1px solid #ddd; border-radius: 4px; } button { padding: 10px; background: #42b983; color: #fff; border: none; border-radius: 4px; cursor: pointer; } button:disabled { background: #999; cursor: not-allowed; } .message { margin-top: 10px; padding: 8px; border-radius: 4px; } .success { background: #d4edda; color: #155724; } .error { background: #f8d7da; color: #721c24; } </style>
关键注意事项
- 邮箱授权码获取:登录对应邮箱(如QQ/Gmail),开启SMTP服务,获取专属授权码,禁止直接使用登录密码。
- 生产环境配置:后端不要硬编码邮箱信息,改用环境变量(如
process.env.EMAIL_USER、process.env.EMAIL_PASS);跨域配置限制允许的域名,不要使用全局cors()。 - 错误处理:可根据后端返回的具体错误信息,优化前端提示内容。
内容的提问来源于stack exchange,提问作者ZheFrench
相关产品推荐
相关产品推荐

