vue怎么实现登录界面
实现登录界面的基础结构
使用Vue CLI或Vite创建一个Vue项目,确保已安装vue-router和状态管理库(如Pinia或Vuex)。登录界面通常包含以下基础元素:
- 用户名/邮箱输入框
- 密码输入框
- 登录按钮
- 可选:记住我、忘记密码等辅助功能
<template>
<div class="login-container">
<form @submit.prevent="handleLogin">
<input v-model="form.username" type="text" placeholder="用户名/邮箱" required>
<input v-model="form.password" type="password" placeholder="密码" required>
<button type="submit">登录</button>
</form>
</div>
</template>
表单数据绑定与验证
通过Vue的v-model实现双向数据绑定,配合计算属性或验证库(如VeeValidate)进行表单验证:

<script setup>
import { ref } from 'vue'
const form = ref({
username: '',
password: ''
})
const validateForm = () => {
return form.value.username.trim() && form.value.password.length >= 6
}
</script>
登录逻辑实现
调用API接口处理登录请求,通常使用axios或fetch发送POST请求。处理成功响应后存储token并跳转页面:
import { useRouter } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
const router = useRouter()
const authStore = useAuthStore()
const handleLogin = async () => {
if (!validateForm()) return
try {
const { data } = await axios.post('/api/login', form.value)
authStore.setToken(data.token)
router.push('/dashboard')
} catch (error) {
alert('登录失败: ' + error.response?.data?.message)
}
}
路由守卫配置
在路由配置中添加元字段,通过全局前置守卫保护需要认证的路由:

// router/index.js
router.beforeEach((to) => {
const isAuthenticated = useAuthStore().isAuthenticated
if (to.meta.requiresAuth && !isAuthenticated) {
return { path: '/login', query: { redirect: to.fullPath } }
}
})
样式优化
使用CSS或UI框架(如Element Plus、Ant Design Vue)美化登录界面。建议添加加载状态和错误提示:
<button :disabled="loading" type="submit">
{{ loading ? '登录中...' : '登录' }}
</button>
<div v-if="error" class="error-message">{{ error }}</div>
安全增强措施
实现基础安全功能:
- 密码输入框添加显示/隐藏切换功能
- 提交时禁用按钮防止重复提交
- 对网络错误进行友好提示
- 在Pinia/Vuex中存储的token应设置为httpOnly的cookie
完整组件示例
<template>
<div class="login-container">
<form @submit.prevent="handleLogin">
<div class="form-group">
<label>用户名</label>
<input v-model="form.username" type="text" required>
</div>
<div class="form-group">
<label>密码</label>
<div class="password-input">
<input v-model="form.password" :type="showPassword ? 'text' : 'password'" required>
<button type="button" @click="showPassword = !showPassword">
{{ showPassword ? '隐藏' : '显示' }}
</button>
</div>
</div>
<button :disabled="loading" type="submit">
{{ loading ? '登录中...' : '登录' }}
</button>
<div v-if="error" class="error">{{ error }}</div>
</form>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
const form = ref({ username: '', password: '' })
const showPassword = ref(false)
const loading = ref(false)
const error = ref('')
const router = useRouter()
const authStore = useAuthStore()
const handleLogin = async () => {
if (!form.value.username || !form.value.password) {
error.value = '请输入用户名和密码'
return
}
loading.value = true
error.value = ''
try {
await authStore.login(form.value)
router.push('/dashboard')
} catch (err) {
error.value = err.message || '登录失败'
} finally {
loading.value = false
}
}
</script>
<style scoped>
.login-container {
max-width: 400px;
margin: 0 auto;
padding: 2rem;
}
.form-group {
margin-bottom: 1rem;
}
.password-input {
display: flex;
}
.error {
color: red;
margin-top: 1rem;
}
</style>






