Vue登录组件Cookie未创建问题求助(附相关代码)
核心问题拆解
1. <script setup>错误使用this
Vue3的<script setup>语法没有this上下文,所有ref声明的变量必须通过.value访问。你代码里大量用this.xxx会导致变量无法正确赋值/读取,Cookie设置代码根本没被执行到。
2. 响应式变量赋值错误
users是ref(null)声明的响应式变量,onMounted中应该用users.value = res.data,而非直接users = res.data,否则users会失去响应式特性,后续遍历users.length会出错。
3. 拼写错误导致验证逻辑失效
email.lenght == 0里的lenght是拼写错误,应为length,这会让邮箱为空的验证逻辑完全失效,后续代码执行异常。
4. 登录校验逻辑未正确触发
由于上述变量访问错误,匹配用户的循环分支根本没执行到,自然不会触发VueCookies.set代码。
5. 其他潜在隐患
- 明文密码存Cookie极度不安全,容易被窃取,建议只存用户ID或生成的Token
window.location.href = '/'会立即刷新页面,后续的alert不会显示- 表单验证未处理
email.value为null的情况,直接访问length可能报错
修复后的完整代码
Vue登录组件修正版
<script setup> import { ref, onMounted } from 'vue' import VueCookies from 'vue-cookies' import axios from 'axios'; const LogInModalVisible = ref(false) const baseURL = 'http://localhost:3000/' const userURL = baseURL + "users"; // 初始化响应式变量,默认值设为空字符串/数组更合理 const users = ref([]) const username = ref('') const email = ref('') const password = ref('') const login = ref(true) const signup = ref(true) const usernameError = ref(null) const emailError = ref(null) const passwordError = ref(null) const passwordValidation = ref(false) const signupvalidation = ref(false) // 全局配置Cookie默认过期时间 VueCookies.config('120min') onMounted(async () => { try { const res = await axios.get(userURL); // 正确给响应式变量赋值 users.value = res.data; console.log(users.value) } catch (e) { console.error('获取用户列表失败:', e) } }) async function loginSubmit() { // 重置错误信息和验证状态 emailError.value = null passwordError.value = null passwordValidation.value = false // 邮箱验证 if (!email.value || email.value.length === 0) { emailError.value = "邮箱不能为空" } // 密码验证 if (!password.value || password.value.length === 0) { passwordError.value = "密码不能为空!"; } else if (password.value.length < 8) { passwordError.value = "密码长度不能少于8位!" } // 有验证错误直接返回,不执行后续逻辑 if (emailError.value || passwordError.value) return // 遍历用户校验登录信息 for (const user of users.value) { if (user.email === email.value) { if (user.password === password.value) { passwordValidation.value = true; // 禁止存明文密码!只存必要用户标识 VueCookies.set('username', user.username, "120min"); VueCookies.set('email', email.value, "120min"); VueCookies.set('id', user.id, "120min"); alert("登录成功"); // 延迟跳转,确保alert能正常显示 setTimeout(() => { window.location.href = '/'; }, 100); return; // 找到匹配用户后直接退出循环 } else { passwordError.value = "密码错误!" return } } } // 遍历完未找到匹配用户 passwordError.value = "邮箱或用户名不存在!" } </script> <template> <div v-if="login"> <el-dialog v-model="LogInModalVisible" title="登录" width="50%" center> <el-form label-position='top' status-icon :label-width="80"> <el-form-item label="邮箱"> <el-input type="email" aria-placeholder="请输入邮箱" v-model="email" /> <div class="input-message" v-if="emailError"> <h6>{{ emailError }}</h6> </div> </el-form-item> <el-form-item label="密码"> <el-input type="password" aria-placeholder="请输入密码" v-model="password" /> <div class="input-message" v-if="passwordError"> <h6>{{ passwordError }}</h6> </div> </el-form-item> </el-form> <div class="footer"> <span> <el-button @click="LogInModalVisible = false">取消</el-button> <el-button type="primary" @click="loginSubmit(); LogInModalVisible = false"> 登录 </el-button> </span> <div class="linkDiv"> <p>还不是会员?</p> <el-link type="primary" @click='login = false'>立即注册!</el-link> </div> </div> </el-dialog> </div> <div v-else> <el-dialog v-model="LogInModalVisible" title="注册" width="50%" center> <el-form label-position='top' status-icon :label-width="80"> <el-form-item label="用户名"> <el-input type="text" aria-placeholder="请输入用户名" v-model="username" /> <div class="input-message" v-if="usernameError"> <h6>{{ usernameError }}</h6> </div> </el-form-item> <el-form-item label="邮箱"> <el-input type="email" aria-placeholder="请输入邮箱" v-model="email" /> <div class="input-message" v-if="emailError"> <h6>{{ emailError }}</h6> </div> </el-form-item> <el-form-item label="密码"> <el-input type="password" aria-placeholder="请输入密码" v-model="password" /> <div class="input-message" v-if="passwordError"> <h6>{{ passwordError }}</h6> </div> </el-form-item> </el-form> <div class="footer"> <span class="dialog-footer"> <el-button @click="LogInModalVisible = false">取消</el-button> <el-button type="primary" @click="LogInModalVisible = false"> 注册 </el-button> </span> <div class="linkDiv"> <p>已经是会员?</p> <el-link type="primary" @click='login = true'>立即登录!</el-link> </div> </div> </el-dialog> </div> </template> <style scoped> .linkDiv{ padding-top: 15px; } p { padding-bottom: 10px; } .footer{ text-align: center; padding-top: 10px; } </style>
额外优化建议
- Cookie安全配置:生产环境设置Cookie时加上
httpOnly: true和secure: true,防止前端脚本读取Cookie,抵御XSS攻击 - 替换明文存储:后端生成JWT等安全Token,前端只存Token,后续请求用Token验证身份,绝对不要存密码
- 表单验证升级:使用Element Plus自带的表单验证规则,比手动写判断更简洁可靠
- 错误提示优化:给用户更清晰的错误提示,比如区分“邮箱不存在”和“密码错误”
内容的提问来源于stack exchange,提问作者Trpimir
相关产品推荐
相关产品推荐

