使用Vue開(kāi)發(fā)登錄頁(yè)面的完整指南
一、項(xiàng)目搭建與基礎(chǔ)配置
環(huán)境準(zhǔn)備
使用 Vue CLI 或 Vite 創(chuàng)建項(xiàng)目,推薦組合:Vue3 + Element Plus + Vue Router
npm create vue@latest npm install element-plus @element-plus/icons-vue vue-router
- 全局配置(main.js)
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import router from './router'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(ElementPlus)
app.use(router)
app.mount('#app')二、登錄頁(yè)面核心實(shí)現(xiàn)
- 模板結(jié)構(gòu)(login.vue)
<template>
<div class="login-container">
<el-form ref="formRef" :model="form" :rules="rules">
<h2 class="title">校園交易平臺(tái)</h2>
<el-form-item prop="username">
<el-input
v-model="form.username"
prefix-icon="User"
placeholder="請(qǐng)輸入手機(jī)號(hào)"
/>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="form.password"
prefix-icon="Lock"
type="password"
show-password
placeholder="請(qǐng)輸入密碼"
@keyup.enter="handleLogin"
/>
</el-form-item>
<el-button
type="primary"
:loading="loading"
@click="handleLogin"
>
登錄
</el-button>
<div class="links">
<router-link to="/register">立即注冊(cè)</router-link>
<router-link to="/forgot">忘記密碼?</router-link>
</div>
</el-form>
</div>
</template>- 數(shù)據(jù)與驗(yàn)證邏輯
<script setup>
import { ref, reactive } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
const form = reactive({
username: '',
password: ''
})
const rules = reactive({
username: [
{ required: true, message: '請(qǐng)輸入手機(jī)號(hào)', trigger: 'blur' },
{ pattern: /^1[3-9]\d{9}$/, message: '手機(jī)號(hào)格式錯(cuò)誤' }
],
password: [
{ required: true, message: '請(qǐng)輸入密碼', trigger: 'blur' },
{ min: 6, max: 16, message: '長(zhǎng)度6-16位' }
]
})
const loading = ref(false)
const formRef = ref(null)
const router = useRouter()
const handleLogin = async () => {
try {
await formRef.value.validate()
loading.value = true
// 模擬API請(qǐng)求
await new Promise(resolve => setTimeout(resolve, 1000))
sessionStorage.setItem('token', 'demo_token')
ElMessage.success('登錄成功')
router.replace('/dashboard')
} catch (error) {
console.error('登錄失敗:', error)
} finally {
loading.value = false
}
}
</script>- 樣式優(yōu)化要點(diǎn)
<style scoped>
.login-container {
height: 100vh;
display: grid;
place-items: center;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
}
.title {
text-align: center;
margin-bottom: 2rem;
color: #2c3e50;
font-size: 1.8rem;
}
:deep(.el-form) {
width: 400px;
padding: 2rem;
background: rgba(255,255,255,0.95);
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0,0,0,0.1);
}
.el-button {
width: 100%;
margin-top: 1rem;
}
.links {
margin-top: 1.5rem;
display: flex;
justify-content: space-between;
a {
color: #409eff;
text-decoration: none;
transition: color 0.3s;
&:hover {
color: #66b1ff;
}
}
}
</style>三、進(jìn)階功能實(shí)現(xiàn)
- 路由守衛(wèi)配置
// router/index.js
router.beforeEach((to) => {
const isAuthenticated = sessionStorage.getItem('token')
if (to.meta.requiresAuth && !isAuthenticated) {
return '/login'
}
if (to.path === '/login' && isAuthenticated) {
return '/dashboard'
}
})- 安全增強(qiáng)方案
密碼加密傳輸(使用crypto-js)
添加驗(yàn)證碼功能
請(qǐng)求限流與防重放攻擊
import CryptoJS from 'crypto-js'
const encryptPassword = (password) => {
return CryptoJS.SHA256(password).toString()
}- 第三方登錄集成
<template>
<div class="oauth-login">
<el-divider>第三方登錄</el-divider>
<div class="oauth-buttons">
<el-button @click="handleWechatLogin">
<svg-icon icon-class="wechat" />
微信登錄
</el-button>
</div>
</div>
</template>四、最佳實(shí)踐與注意事項(xiàng)
表單驗(yàn)證優(yōu)化
異步驗(yàn)證手機(jī)號(hào)是否注冊(cè)
密碼強(qiáng)度實(shí)時(shí)檢測(cè)
const checkUsername = async (rule, value, callback) => {
if (!value) return callback(new Error('請(qǐng)輸入手機(jī)號(hào)'))
if (!/^1[3-9]\d{9}$/.test(value)) return callback(new Error('格式錯(cuò)誤'))
try {
const { data } = await api.checkUsername(value)
if (!data.exist) callback(new Error('該用戶未注冊(cè)'))
} catch (error) {
callback(new Error('驗(yàn)證失敗'))
}
}- 用戶體驗(yàn)優(yōu)化
自動(dòng)填充最近登錄賬號(hào)
記住密碼功能(加密存儲(chǔ))
加載狀態(tài)管理
// 自動(dòng)填充
const lastUsername = localStorage.getItem('lastUsername')
if (lastUsername) form.username = lastUsername
// 記住密碼
const savePassword = ref(false)
watch(savePassword, (val) => {
if (val) {
localStorage.setItem('remembered', JSON.stringify(form))
} else {
localStorage.removeItem('remembered')
}
})- 錯(cuò)誤處理規(guī)范
try {
const res = await loginApi(formData)
if (res.code === 1001) {
ElMessage.warning('該賬號(hào)已被凍結(jié)')
}
} catch (err) {
ElMessage.error({
message: `登錄失敗: ${err.message}`,
grouping: true // 相同錯(cuò)誤合并顯示
})
}五、典型問(wèn)題解決方案
跨域問(wèn)題處理
// vite.config.js
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://backend.example.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
})- 響應(yīng)式布局適配
@media (max-width: 768px) {
.login-container {
padding: 1rem;
:deep(.el-form) {
width: 100%;
margin: 0 1rem;
}
}
}瀏覽器兼容問(wèn)題
使用@vitejs/plugin-legacy處理ES6+語(yǔ)法
添加autoprefixer自動(dòng)補(bǔ)全CSS前綴
到此這篇關(guān)于使用Vue開(kāi)發(fā)登錄頁(yè)面的完整指南的文章就介紹到這了,更多相關(guān)Vue開(kāi)發(fā)登錄頁(yè)面內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue3表單參數(shù)校驗(yàn)及正則表達(dá)式舉例詳解
最近項(xiàng)目中有一個(gè)校驗(yàn)身份證號(hào)手機(jī)號(hào)的業(yè)務(wù),索性給大家總結(jié)下,這篇文章主要給大家介紹了關(guān)于vue3表單參數(shù)校驗(yàn)及正則表達(dá)式的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-04-04
前端vue中實(shí)現(xiàn)文件下載的幾種方法總結(jié)
這篇文章主要介紹了前端vue中實(shí)現(xiàn)文件下載的幾種方法總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
vue動(dòng)態(tài)綁定圖標(biāo)的完整步驟
動(dòng)態(tài)綁定是我們?nèi)粘i_(kāi)發(fā)中經(jīng)常遇到的一個(gè)需求,下面這篇文章主要給大家介紹了關(guān)于vue動(dòng)態(tài)綁定圖標(biāo)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-05-05
vue滾動(dòng)軸插件better-scroll使用詳解
這篇文章主要為大家詳細(xì)介紹了vue滾動(dòng)軸插件better-scroll的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10
vue style屬性設(shè)置背景圖片的相對(duì)路徑無(wú)效的解決
這篇文章主要介紹了vue style屬性設(shè)置背景圖片的相對(duì)路徑無(wú)效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
Vue3實(shí)現(xiàn)組件級(jí)基類的多種方法
vue3提供了 mixins和extends,但是嘗試之后發(fā)現(xiàn)這兩種方法只支持純OptionAPI,設(shè)置的data會(huì)被識(shí)別,但是設(shè)置的setup里return 的 reactive,完全無(wú)效,setup也沒(méi)有被執(zhí)行,這篇文章主要介紹了Vue3實(shí)現(xiàn)組件級(jí)基類的幾種方法,需要的朋友可以參考下2023-04-04
vue3?組合式api中?ref?和$parent?的使用方法
vue3中, 在 組件中添加一個(gè) component ref=“xxx” ,就可以在父組件中得到 子組件的 dom 對(duì)象, 以及 虛擬的 dom 對(duì)象, 有了虛擬 dom, 我們就可以在父組件中控制子組件的顯示了,這篇文章主要介紹了vue3組合式api中ref和$parent的使用,需要的朋友可以參考下2023-09-09
vue - vue.config.js中devServer配置方式
今天小編就為大家分享一篇vue - vue.config.js中devServer配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-10-10

