This code snippet provides a user-friendly login popup component built with Vue.js. It includes a toggle between login and registration forms, basic validation, and error handling for a smooth user experience.
A Pen by Kevin Marville on CodePen.
<template> | |
<div id="app"> | |
<div class="onboarding" v-if="showOnboarding"> | |
<div class="modal" v-show="showLogin"> | |
<h2>Welcome!</h2> | |
<div class="tabs"> | |
<button :class="{ active: activeTab === 'login' }" @click="changeTab('login')">Login</button> | |
<button :class="{ active: activeTab === 'register' }" @click="changeTab('register')">Register</button> | |
</div> | |
<div class="content"> | |
<form v-if="activeTab === 'login'" @submit.prevent="login"> | |
<label for="username">Username</label> | |
<input type="text" id="username" v-model="username" required> | |
<label for="password">Password</label> | |
<input type="password" id="password" v-model="password" required> | |
<div v-if="loginError" class="error">{{ loginError }}</div> | |
<button type="submit">Login</button> | |
<a href="#">Forgot Your Password?</a> | |
</form> | |
<form v-if="activeTab === 'register'" @submit.prevent="register"> | |
<label for="registerUsername">Username</label> | |
<input type="text" id="registerUsername" v-model="registerUsername" required> | |
<label for="registerPassword">Password</label> | |
<input type="password" id="registerPassword" v-model="registerPassword" required> | |
<div v-if="registerError" class="error">{{ registerError }}</div> | |
<button type="submit">Register</button> | |
</form> | |
</div> | |
<button @click="showLogin = false">Close</button> | |
</div> | |
</div> | |
</div> | |
</template> | |
<script> | |
export default { | |
data() { | |
return { | |
showOnboarding: true, | |
showLogin: true, | |
activeTab: 'login', | |
username: '', | |
password: '', | |
registerUsername: '', | |
registerPassword: '', | |
loginError: null, | |
registerError: null, | |
}; | |
}, | |
methods: { | |
changeTab(tab) { | |
this.activeTab = tab; | |
this.loginError = null; | |
this.registerError = null; | |
}, | |
login() { | |
if (this.username === 'admin' && this.password === 'admin') { | |
this.showLogin = false; | |
this.showOnboarding = false; | |
} else { | |
this.loginError = 'Invalid username or password'; | |
} | |
}, | |
register() { | |
// Registration logic | |
this.registerError = 'Registration not implemented'; | |
}, | |
}, | |
}; | |
</script> | |
<style> | |
#app { | |
font-family: Avenir, Helvetica, Arial, sans-serif; | |
text-align: center; | |
color: #2c3e50; | |
margin-top: 60px; | |
} | |
.onboarding { | |
position: fixed; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
background: rgba(0, 0, 0, 0.7); | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
justify-content: center; | |
padding: 20px; | |
} | |
.modal { | |
background: #fff; | |
color: #000; | |
padding: 20px; | |
border-radius: 10px; | |
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); | |
width: 90%; | |
max-width: 400px; | |
margin: 20px auto; | |
text-align: left; | |
} | |
.tabs { | |
display: flex; | |
justify-content: center; | |
margin-bottom: 20px; | |
} | |
.tabs button { | |
background: none; | |
border: none; | |
padding: 10px 20px; | |
cursor: pointer; | |
font-size: 1em; | |
transition: background 0.3s; | |
} | |
.tabs button.active { | |
background: #4fc08d; | |
color: #fff; | |
border-radius: 5px; | |
} | |
.tabs button:hover { | |
background: #3da76f; | |
} | |
.modal label { | |
display: block; | |
margin-bottom: 5px; | |
} | |
.modal input { | |
width: 100%; | |
padding: 10px; | |
margin-bottom: 20px; | |
border: 1px solid #ddd; | |
border-radius: 5px; | |
} | |
.modal button { | |
background: #4fc08d; | |
color: #fff; | |
border: none; | |
padding: 10px 20px; | |
border-radius: 5px; | |
cursor: pointer; | |
font-size: 1em; | |
transition: background 0.3s; | |
} | |
.modal button:hover { | |
background: #3da76f; | |
} | |
.modal a { | |
color: #4fc08d; | |
text-decoration: none; | |
display: block; | |
margin-top: 10px; | |
} | |
.error { | |
color: red; | |
margin-bottom: 10px; | |
} | |
</style> |
This code snippet provides a user-friendly login popup component built with Vue.js. It includes a toggle between login and registration forms, basic validation, and error handling for a smooth user experience.
A Pen by Kevin Marville on CodePen.