教程
- 简介 | Vue.js
- 最全系列的vue3入门教程『图文并茂』-腾讯云开发者社区-腾讯云
- Vue3 教程 | 菜鸟教程
- 最全最新Vue、Vuejs教程,从入门到精通_哔哩哔哩_bilibili
在线编辑器
Vue3演练场,在线编辑,实时预览、在线运行。
登录注册页面实例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户注册登录系统</title>
<!-- 引入Vue.js -->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<!-- 引入Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- 引入Font Awesome -->
<link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
<!-- 配置Tailwind自定义颜色 -->
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#3B82F6',
secondary: '#10B981',
danger: '#EF4444',
dark: '#1F2937'
},
fontFamily: {
inter: ['Inter', 'system-ui', 'sans-serif'],
},
}
}
}
</script>
<!-- 自定义工具类 -->
<style type="text/tailwindcss">
@layer utilities {
.content-auto {
content-visibility: auto;
}
.form-input-focus {
@apply focus:ring-2 focus:ring-primary/50 focus:border-primary focus:outline-none;
}
.btn-primary {
@apply bg-primary hover:bg-primary/90 text-white font-medium py-2 px-4 rounded-lg transition-all duration-300;
}
.btn-secondary {
@apply bg-white border border-gray-300 hover:bg-gray-50 text-dark font-medium py-2 px-4 rounded-lg transition-all duration-300;
}
}
</style>
</head>
<body class="bg-gray-50 font-inter min-h-screen flex items-center justify-center p-4">
<div id="app" class="w-full max-w-md">
<!-- 卡片容器 -->
<div class="bg-white rounded-xl shadow-lg overflow-hidden transition-all duration-500 transform hover:shadow-xl">
<!-- 标题区域 -->
<div class="bg-primary text-white p-6 text-center">
<h1 class="text-[clamp(1.5rem,3vw,2rem)] font-bold">
{{ isLoginMode ? '用户登录' : '用户注册' }}
</h1>
<p class="opacity-90 mt-1">
{{ isLoginMode ? '欢迎回来,请登录您的账号' : '创建新账号,开始您的旅程' }}
</p>
</div>
<!-- 表单区域 -->
<div class="p-6">
<form @submit.prevent="isLoginMode ? handleLogin() : handleRegister" class="space-y-4">
<!-- 用户名输入 -->
<div>
<label for="username" class="block text-sm font-medium text-gray-700 mb-1">
<i class="fa fa-user mr-1"></i>用户名
</label>
<div class="relative">
<span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
<i class="fa fa-user"></i>
</span>
<input
type="text"
id="username"
v-model="username"
required
class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg form-input-focus"
placeholder="请输入用户名"
>
</div>
</div>
<!-- 密码输入 -->
<div>
<label for="password" class="block text-sm font-medium text-gray-700 mb-1">
<i class="fa fa-lock mr-1"></i>密码
</label>
<div class="relative">
<span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
<i class="fa fa-lock"></i>
</span>
<input
:type="showPassword ? 'text' : 'password'"
id="password"
v-model="password"
required
class="w-full pl-10 pr-10 py-2 border border-gray-300 rounded-lg form-input-focus"
placeholder="请输入密码"
>
<button
type="button"
@click="showPassword = !showPassword"
class="absolute inset-y-0 right-0 flex items-center pr-3 text-gray-500 hover:text-primary transition-colors"
>
<i :class="showPassword ? 'fa fa-eye-slash' : 'fa fa-eye'"></i>
</button>
</div>
</div>
<!-- 确认密码 (仅注册模式显示) -->
<div v-if="!isLoginMode">
<label for="confirmPassword" class="block text-sm font-medium text-gray-700 mb-1">
<i class="fa fa-check-circle mr-1"></i>确认密码
</label>
<div class="relative">
<span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-500">
<i class="fa fa-check-circle"></i>
</span>
<input
:type="showConfirmPassword ? 'text' : 'password'"
id="confirmPassword"
v-model="confirmPassword"
required
class="w-full pl-10 pr-10 py-2 border border-gray-300 rounded-lg form-input-focus"
placeholder="请再次输入密码"
>
<button
type="button"
@click="showConfirmPassword = !showConfirmPassword"
class="absolute inset-y-0 right-0 flex items-center pr-3 text-gray-500 hover:text-primary transition-colors"
>
<i :class="showConfirmPassword ? 'fa fa-eye-slash' : 'fa fa-eye'"></i>
</button>
</div>
</div>
<!-- 错误提示 -->
<div v-if="errorMessage" class="bg-danger/10 text-danger text-sm p-3 rounded-lg flex items-start">
<i class="fa fa-exclamation-circle mt-0.5 mr-2"></i>
<span>{{ errorMessage }}</span>
</div>
<!-- 成功提示 -->
<div v-if="successMessage" class="bg-secondary/10 text-secondary text-sm p-3 rounded-lg flex items-start">
<i class="fa fa-check-circle mt-0.5 mr-2"></i>
<span>{{ successMessage }}</span>
</div>
<!-- 提交按钮 -->
<button
type="submit"
class="w-full btn-primary flex items-center justify-center"
>
<i :class="isLoginMode ? 'fa fa-sign-in mr-2' : 'fa fa-user-plus mr-2'"></i>
{{ isLoginMode ? '登录' : '注册' }}
</button>
</form>
<!-- 切换模式链接 -->
<div class="mt-6 text-center">
<p class="text-gray-600 text-sm">
{{ isLoginMode ? '还没有账号?' : '已有账号?' }}
<button
@click="toggleMode"
class="text-primary font-medium hover:underline ml-1 focus:outline-none focus:text-primary/80"
>
{{ isLoginMode ? '立即注册' : '立即登录' }}
</button>
</p>
</div>
</div>
</div>
<!-- 已登录用户信息 -->
<div v-if="isLoggedIn" class="mt-6 bg-white rounded-xl shadow-lg p-6 text-center">
<div class="text-secondary text-4xl mb-3">
<i class="fa fa-check-circle"></i>
</div>
<h2 class="text-xl font-bold text-dark mb-2">登录成功!</h2>
<p class="text-gray-600 mb-4">欢迎回来,{{ loggedInUser }}!</p>
<button
@click="handleLogout"
class="btn-secondary flex items-center justify-center mx-auto"
>
<i class="fa fa-sign-out mr-2"></i>退出登录
</button>
</div>
</div>
<script>
// 创建Vue应用
const { createApp } = Vue;
createApp({
data() {
return {
// 模式切换:true为登录模式,false为注册模式
isLoginMode: true,
// 表单数据
username: '',
password: '',
confirmPassword: '',
// 密码显示控制
showPassword: false,
showConfirmPassword: false,
// 提示信息
errorMessage: '',
successMessage: '',
// 登录状态
isLoggedIn: false,
loggedInUser: ''
}
},
methods: {
/**
* 切换登录/注册模式
*/
toggleMode() {
// 切换模式时重置表单和提示信息
this.isLoginMode = !this.isLoginMode;
this.username = '';
this.password = '';
this.confirmPassword = '';
this.errorMessage = '';
this.successMessage = '';
},
/**
* 处理注册逻辑
*/
handleRegister() {
// 清除之前的提示
this.errorMessage = '';
this.successMessage = '';
// 表单验证
if (!this.username.trim() || !this.password.trim()) {
this.errorMessage = '用户名和密码不能为空';
return;
}
if (this.password !== this.confirmPassword) {
this.errorMessage = '两次输入的密码不一致';
return;
}
if (this.password.length < 6) {
this.errorMessage = '密码长度不能少于6位';
return;
}
// 获取已存储的用户列表
const users = this.getUsersFromStorage();
// 检查用户名是否已存在
if (users.some(user => user.username === this.username.trim())) {
this.errorMessage = '该用户名已被注册';
return;
}