You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue登录组件Cookie未创建问题求助(附相关代码)

无法创建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>

额外优化建议

  1. Cookie安全配置:生产环境设置Cookie时加上httpOnly: true和secure: true,防止前端脚本读取Cookie,抵御XSS攻击
  2. 替换明文存储:后端生成JWT等安全Token,前端只存Token,后续请求用Token验证身份,绝对不要存密码
  3. 表单验证升级:使用Element Plus自带的表单验证规则,比手动写判断更简洁可靠
  4. 错误提示优化:给用户更清晰的错误提示,比如区分“邮箱不存在”和“密码错误”

内容的提问来源于stack exchange,提问作者Trpimir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 08:25:58