前言
在当今数字化时代,一个直观且美观的登录和注册页面是给用户留下良好第一印象的关键。
对于前端开发者来说,借助强大的编程工具可以事半功倍地完成这一任务。
在这里,我将分享如何使用 Cursor 设计工具打造一个现代化的登录和注册页面。
认识 Cursor 编辑器
Cursor 是一款集成了先进 AI 技术的代码生成工具,它能够帮助开发者快速生成高质量的前端代码。用户只需要上传设计草图或者描述设计需求,Cursor 就可以生成相应的 HTML、CSS 和 JavaScript 代码,从而大大节省了从设计到开发的时间。
准备设计草图
在开始编码之前,你需要准备好登录和注册页面的设计草图。可以使用专业设计软件如 Figma、Adobe XD 等创建这些草图。设计时要确保页面布局合理、元素风格统一,并且考虑到不同设备的响应式设计。
利用 Cursor 生成代码
上传设计草图至 Cursor
将你精心设计的登录、注册页面草图上传到 Cursor 平台。在上传过程中,你可以选择是否允许 Cursor 对设计进行优化建议,以确保最终生成的代码质量。(如果木有的话可以使用文本描述)
生成前端代码
Cursor 便会根据你的设计和描述自动生成前端代码。
在这个过程中,你还可以指定需要的文件结构和代码风格,使生成的代码更符合你的项目规范。
建议是在项目新建一个cursorrules,这样ai生成的代码会更加听话
下面是cursor生成的页面元素代码
<template>
<div class="flex justify-center items-center min-h-screen bg-gradient-to-r from-blue-100 via-purple-50 to-pink-50">
<div class="w-full max-w-md transition-all duration-300 transform login-card">
<div class="p-8 space-y-6 bg-white rounded-2xl shadow-2xl">
<!-- Logo区域 -->
<div class="text-center">
<div class="inline-block p-4 mb-4 bg-blue-50 rounded-full">
<img src="@/assets/logo.jpg" alt="logo" class="w-16 h-16 rounded-full">
</div>
<h2 class="mb-2 text-3xl font-bold text-gray-900">
{{ isLogin ? '欢迎回来' : '创建账号' }}
</h2>
<p class="mb-8 text-sm text-gray-600">
{{ isLogin ? '还没有账号?' : '已有账号?' }}
<a href="javascript:;" @click="toggleForm"
class="font-medium text-blue-600 transition-colors hover:text-blue-700">
{{ isLogin ? '立即注册' : '立即登录' }}
</a>
</p>
</div>
<!-- 登录表单 -->
<a-form v-if="isLogin" :model="formState" :rules="loginRules" class="space-y-6"
@finish="handleLoginSubmit">
<div class="space-y-4">
<a-form-item name="email">
<a-input v-model:value="formState.email" size="large" placeholder="邮箱" class="login-input">
<template #prefix>
<UserOutlined class="text-gray-400" />
</template>
</a-input>
</a-form-item>
<a-form-item name="password">
<a-input-password v-model:value="formState.password" size="large" placeholder="密码"
class="login-input">
<template #prefix>
<LockOutlined class="text-gray-400" />
</template>
</a-input-password>
</a-form-item>
</div>
<div class="flex justify-between items-center">
<a-form-item name="remember" no-style>
<a-checkbox v-model:checked="formState.remember">
<span class="text-gray-600">记住我</span>
</a-checkbox>
</a-form-item>
<router-link to="/forgot-password"
class="text-sm text-blue-600 transition-colors hover:text-blue-700">
忘记密码?
</router-link>
</div>
<div>
<a-button :loading="loading" type="primary" html-type="submit"
class="w-full h-12 text-lg font-medium login-button">
{{ '登录' }}
</a-button>
</div>
</a-form>
<!-- 注册表单 -->
<a-form v-else :model="registerFormState" :rules="registerRules" class="space-y-6"
@finish="handleRegisterSubmit">
<div class="space-y-4">
<a-form-item name="nickname">
<a-input v-model:value="registerFormState.nickname" size="large" placeholder="用户名"
class="login-input">
<template #prefix>
<UserOutlined class="text-gray-400" />
</template>
</a-input>
</a-form-item>
<a-form-item name="email">
<a-input v-model:value="registerFormState.email" size="large" placeholder="邮箱"
class="login-input">
<template #prefix>
<MailOutlined class="text-gray-400" />
</template>
</a-input>
</a-form-item>
<a-form-item name="password">
<a-input-password v-model:value="registerFormState.password" size="large" placeholder="密码"
class="login-input">
<template #prefix>
<LockOutlined class="text-gray-400" />
</template>
</a-input-password>
</a-form-item>
<a-form-item name="confirmPassword">
<a-input-password v-model:value="registerFormState.confirmPassword" size="large"
placeholder="确认密码" class="login-input">
<template #prefix>
<LockOutlined class="text-gray-400" />
</template>
</a-input-password>
</a-form-item>
</div>
<div>
<a-form-item name="agreement">
<a-checkbox v-model:checked="registerFormState.agreement">
<span class="text-gray-600">我已阅读并同意
<a href="javascript:;" class="text-blue-600 hover:text-blue-700">用户协议</a>
和
<a href="javascript:;" class="text-blue-600 hover:text-blue-700">隐私政策</a>
</span>
</a-checkbox>
</a-form-item>
</div>
<div>
<a-button :loading="loading" type="primary" html-type="submit"
class="w-full h-12 text-lg font-medium login-button">
注册
</a-button>
</div>
</a-form>
<!-- 其他登录方式 -->
<div class="pt-4">
<div class="relative">
<div class="flex absolute inset-0 items-center">
<div class="w-full border-t border-gray-200"></div>
</div>
<div class="flex relative justify-center text-sm">
<span class="px-4 text-gray-500 bg-white">其他登录方式</span>
</div>
</div>
<div class="grid grid-cols-3 gap-3 mt-6">
<a-button class="social-button" @click="handleGithubLogin">
<GithubOutlined class="text-lg" />
</a-button>
<a-button class="social-button">
<QqOutlined class="text-lg" />
</a-button>
<a-button class="social-button">
<WeiboOutlined class="text-lg" />
</a-button>
</div>
</div>
</div>
</div>
</div>
</template>
自定义与优化
融入项目风格
尽管 Cursor 生成的代码质量很高,但为了使登录与注册页面更好地融入整个项目的设计风格,通常需要进行一些自定义调整。
这包括修改颜色主题、字体样式、按钮形状等,以确保视觉上的一致性。
对应的css样式代码如下
<style scoped>
.login-card {
perspective: 1000px;
}
.login-card:hover {
transform: translateY(-5px);
}
.login-input {
@apply rounded-lg border-gray-200 hover:border-blue-500 focus:border-blue-500;
transition: all 0.3s ease;
}
.login-input:hover {
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
}
.login-button {
@apply rounded-lg bg-gradient-to-r from-blue-500 to-blue-600 hover:from-blue-600 hover:to-blue-700;
transition: all 0.3s ease;
}
.login-button:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);
}
.social-button {
@apply flex justify-center items-center w-full py-2 px-4 border border-gray-200 rounded-lg hover:border-blue-500 hover:text-blue-500 transition-all duration-300;
}
.social-button:hover {
transform: translateY(-2px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
/* 添加输入框动画效果 */
:deep(.ant-input-affix-wrapper) {
transition: all 0.3s ease;
}
:deep(.ant-input-affix-wrapper:hover) {
border-color: #4096ff;
}
:deep(.ant-input-affix-wrapper-focused) {
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
}
</style>
优化交互体验
进一步优化页面的交互细节,例如输入框的焦点效果、按钮的悬停状态、表单验证的即时反馈等。这些细致的交互设计能够让用户体验更加流畅自然。
添加功能代码
将生成的页面代码与后端服务连接起来,实现真正的登录和注册功能。
这一步骤需要编写相应的 JavaScript 代码来处理用户输入、与后端 API 进行交互以及处理返回的响应。
你可以将后端的api接口一起给到cursor,这样也可以大大减轻你的工作量,快乐摸鱼~
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { message } from 'ant-design-vue';
import { UserOutlined, LockOutlined, GithubOutlined, QqOutlined, WeiboOutlined, MailOutlined } from '@ant-design/icons-vue';
import type { FormState, RegisterFormState } from '@/types/form';
import { login, register, githubLogin } from '@/api/auth';
import { useUserStore } from '@/stores/userStore';
const router = useRouter();
const route = useRoute();
const loading = ref(false);
const githubLoading = ref(false);
const isLogin = ref(true);
const userStore = useUserStore();
const formState = reactive<FormState>({
email: '',
nickname: '',
password: '',
remember: true,
});
const registerFormState = reactive<RegisterFormState>({
nickname: '',
email: '',
password: '',
confirmPassword: '',
agreement: false,
});
const loginRules = {
email: [
{ required: true, message: '请输入邮箱', trigger: 'blur' },
{ type: 'email', message: '请输入有效的邮箱地址', trigger: 'blur' },
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, message: '密码至少6个字符', trigger: 'blur' },
],
};
const registerRules = {
nickname: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 4, message: '用户名至少4个字符', trigger: 'blur' },
],
email: [
{ required: true, message: '请输入邮箱', trigger: 'blur' },
{ type: 'email', message: '请输入有效的邮箱地址', trigger: 'blur' },
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, message: '密码至少6个字符', trigger: 'blur' },
],
confirmPassword: [
{ required: true, message: '请确认密码', trigger: 'blur' },
{
validator: (rule: any, value: string) => {
if (value === registerFormState.password) {
return Promise.resolve();
}
return Promise.reject('两次输入的密码不一致');
}, trigger: 'blur'
},
],
agreement: [
{
validator: (rule: any, value: boolean) => {
if (value) {
return Promise.resolve();
}
return Promise.reject('请阅读并同意用户协议');
}, trigger: 'change'
},
],
};
const handleLoginSubmit = async () => {
try {
loading.value = true;
const { data } = await login(formState);
if (data?.token) {
userStore.setToken(data.token);
userStore.setUserInfo({
avatarUrl: data.avatarUrl,
nickname: data.nickname,
roles: data.role,
email: data.email,
id: data.id
});
message.success('登录成功');
const redirect = route.query.redirect as string;
router.push(redirect || '/');
}
} catch (error: any) {
message.error(error.message || '登录失败');
} finally {
loading.value = false;
}
};
const handleRegisterSubmit = async () => {
try {
loading.value = true;
const { data } = await register(registerFormState);
if (data) {
message.success('注册成功,请登录');
isLogin.value = true;
}
} catch (error: any) {
message.error(error.message || '注册失败');
} finally {
loading.value = false;
}
};
const toggleForm = () => {
isLogin.value = !isLogin.value;
};
function handleGithubLogin() {
// 获取当前页面地址的域名
const currentUrl = window.location.origin + '/#/login';
const url = `https://github.com/login/oauth/authorize?client_id=${import.meta.env.VITE_GITHUB_CLIENT_ID}&redirect_uri=${currentUrl}`;
window.location.href = url;
}
// 跳转回登录页面,拿到code,进行登录
async function handleGithubCallback() {
const searchParams = new URLSearchParams(window.location.search);
const code = searchParams.get('code');
console.log(code);
if (!code) return
const { data } = await githubLogin(code as string);
console.log("🚀 ~ handleGithubCallback ~ data:", data)
if (data?.token) {
userStore.setToken(data.token);
userStore.setUserInfo({
avatarUrl: data.avatarUrl,
nickname: data.nickname,
roles: data.role,
email: data.email,
id: data.id
});
message.success('登录成功');
// 跳转回首页去掉code
const cleanUrl = new URL(window.location.href);
cleanUrl.searchParams.delete('code');
window.history.replaceState(null, '', cleanUrl.toString());
router.push('/');
}
}
onMounted(() => {
handleGithubCallback();
});
</script>
最终效果
页面看起来就高大上,也是符合我们的描述,ai还是很强的
登录页面
注册页面
测试与部署
在完成所有自定义和功能开发后,需要进行全面的测试。
测试内容包括页面在不同浏览器和设备上的兼容性、表单验证逻辑的准确性以及与后端交互的稳定性。
通过以上步骤,你就可以利用 Cursor 高效地打造一个既美观又实用的前端登录和注册页面。