前言
技術棧是 uni-app + uView2.0 + Vue.js
本教程的影片版本已釋出在B站,歡迎交流~
戳我看影片:靜夜Coding-無人聲程式設計-機械鍵盤純享版
準備工作
下載UI元件uView UI,作為uni-app外掛引入,下載地址在這裡
登入頁面
先寫好HTML骨架:
新建頁面檔案index.vue
,檔案路徑是pages/index/index.vue
<template>
<view class="login-page">
<u--image src="/static/login-bg.png" class="image-bg" mode="aspectFit" width="100%"></u--image>
<view class="form-content">
<u--form>
<u-form-item>
<u-icon name="account" size="24px"></u-icon>
<u--input placeholder="請輸入使用者名稱" border="bottom" v-model="username"></u--input>
</u-form-item>
<u-form-item>
<u-icon name="lock" size="24px"></u-icon>
<u--input placeholder="請輸入密碼" border="bottom" v-model="password" clearable :password="showPwd">
<template slot="suffix">
<view class="slot-list">
<u-icon :name="showPwd ? 'eye-off' : 'eye-fill'" @click="showPassword"
style="padding: 0 5px;"
></u-icon>
<u--text text="忘記密碼" size="12"></u--text>
</view>
</template>
</u--input>
</u-form-item>
</u--form>
</view>
<view class="btn-list">
<u-button text="立即登入" type="primary" size="large" @click="onSubmit"></u-button>
<u-button text="註冊" type="primary" size="large"
:plain="true" :hairline="true" @click="navRegister"
></u-button>
</view>
<view class="third-party-login">
<u-icon name="weixin-circle-fill" size="36px" color="#2cba00"></u-icon>
<u-icon name="zhifubao-circle-fill" size="36px" color="#019be1"></u-icon>
<u-icon name="weibo-circle-fill" size="36px" color="#df2125"></u-icon>
</view>
<u-radio-group v-model="agreeTerms" style="justify-content: center;align-items: center">
<u-radio shape="circle" name="1"></u-radio>
<span style="font-size: 12px">我已閱讀並同意
<span style="color: #3c9cff">《使用者協議》</span>和<span style="color: #3c9cff">《隱私協議》</span>
</span>
</u-radio-group>
<u-toast ref="uToast"></u-toast>
</view>
</template>
頁面雛形就出來了
接下里我們用css修飾頁面佈局和顏色:
這裡使用了flex佈局
<style>
.login-page {
display: flex;
flex-direction: column;
padding: 2rem 2rem;
}
.image-bg {
align-items: center;
}
.form-content {
padding: 1rem 0rem;
}
.third-party-login {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 1rem 2rem;
gap: 0.5rem;
}
.slot-list {
display: flex;
flex-direction: row;
}
.btn-list {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
</style>
嗯,現在頁面就很漂亮了
接下來補充業務邏輯程式碼:
使用javascript編寫邏輯,它負責包括提交表單、請求API介面、與後端互動和控制動態彈窗等工作
還需要用到瀏覽器的本地儲存能力localStorage
來儲存後端返回的登入token,以便後續訪問其他需要登入的介面
<script>
import {userAccountLogin} from '../../config/api.js'
export default {
data() {
return {
username: "",
password: "",
showPwd: true,
agreeTerms: 1,
}
},
methods: {
showPassword() {
this.showPwd = !this.showPwd
},
// 提交表單
onSubmit() {
if (this.agreeTerms != 1) {
this.$refs.uToast.show({
message: '請先勾選同意使用者協議'
})
return
}
userAccountLogin({
username: this.username,
password: this.password
}).then(res => {
this.$refs.uToast.show({
message: '登入成功',
complete() {
// 儲存登入態TOKEN
uni.setStorageSync('token', res.token)
uni.navigateTo({
url: '/pages/index/userinfo'
})
}
})
})
},
// 跳轉註冊頁面
navRegister() {
uni.navigateTo({
url: '/pages/index/register'
})
}
}
}
</script>
登入成功會跳轉到使用者資訊頁面
使用者資訊頁面
這裡我們寫一個簡單的使用者卡片來展示使用者資料,然後還有一個修改暱稱的功能,點選修改按鈕,會跳出彈窗給使用者修改自己的暱稱。
一共涉及到兩個和後端互動的介面,一是獲取使用者資訊,而是修改使用者暱稱。
新建頁面 userinfo.vue
<template>
<view>
<div class="usercard">
<div class="baseinfo">
<div class="avatar">
<u--image src="/static/logo.png" mode="aspectFit" width="60px"></u--image>
</div>
<div class="nameinfo">
<p>暱稱:{{ userinfo.nickname == '' ? '使用者' + userinfo.id : userinfo.nickname }}</p>
<p>UID:{{ userinfo.id }}</p>
</div>
</div>
<div class="userinfo">
<p>使用者名稱:{{ userinfo.username }}</p>
<p>註冊時間:{{ userinfo.created_at }}</p>
</div>
</div>
<div class="edit-info">
<u-popup :show="show" mode="center" @close="close" @open="open" round="10"
overlayOpacity="0.3" customStyle="width:70%;padding:10px;">
<view>
<u--form>
<u-form-item>
<u-icon name="account" size="24px"></u-icon>
<u--input placeholder="請輸入新的暱稱" v-model="nickname"></u--input>
</u-form-item>
</u--form>
<u-button @click="updateInfo" type="primary" icon="checkmark" size="small">
儲存
</u-button>
</view>
</u-popup>
<u-button @click="show=true" type="primary" icon="edit-pen">修改暱稱</u-button>
</div>
</view>
</template>
<script>
import {userAccountGetInfo, userAccountUpdateInfo} from '../../config/api.js'
export default {
data() {
return {
userinfo: {},
show: false,
nickname: "",
}
},
methods: {
open() {
},
close() {
this.show = false
},
getUserInfo() {
userAccountGetInfo().then(data => {
this.userinfo = data
this.nickname = data.nickname
})
},
updateInfo() {
userAccountUpdateInfo({
nickname: this.nickname
}).then(() => {
this.close()
})
// 重新整理使用者資訊
this.getUserInfo()
}
},
onLoad() {
this.getUserInfo()
}
}
</script>
<style lang="scss">
.baseinfo {
display: flex;
flex-direction: row;
align-items: center;
width: 80%;
height: 80px;
padding: 1rem;
gap: 0.5rem;
.avatar {
display: flex;
}
.nameinfo {
display: flex;
flex-direction: column;
gap: 10px;
}
}
.userinfo {
padding: 0 1rem 1rem 1rem;
p {
margin-bottom: 10px;
}
}
.usercard {
padding: 0.5rem;
border-radius: 20px;
border: 1px solid $u-border-color;
margin: 5px;
background: linear-gradient(275deg, $u-primary-disabled, $u-primary-light);
box-shadow: 14px 8px 14px 3px rgba(43, 98, 169, 0.5);
}
</style>
細心的讀者會注意到css樣式的style標籤有一個屬性<style lang="scss">
和登入頁面的有些不同,這裡我們是用了scss語法來使得css可以支援巢狀語法,這樣對於多層巢狀的樣式程式碼來說便於閱讀和維護。
接下來我們繼續完成註冊頁面
註冊頁面
註冊頁面的骨架和登入頁面大同小異,都要求使用者填寫使用者名稱和密碼,只不過多了一個確認密碼的欄位。稍微修改下javascript程式碼就可以了。
新建頁面 register.vue
<template>
<view class="page-content">
<u--image src="/static/register-bg.png" mode="aspectFit"></u--image>
<view class="form-content">
<u--form>
<u-form-item>
<u-icon name="account" size="24px"></u-icon>
<u--input placeholder="請輸入使用者名稱" border="bottom" v-model="username"></u--input>
</u-form-item>
<u-form-item>
<u-icon name="lock" size="24px"></u-icon>
<u--input placeholder="請輸入密碼" border="bottom" v-model="password" clearable :password="showPwd">
<template slot="suffix">
<view class="slot-list">
<u-icon :name="showPwd ? 'eye-off' : 'eye-fill'" @click="showPassword"
style="padding: 0 5px;"
></u-icon>
</view>
</template>
</u--input>
</u-form-item>
<u-form-item>
<u-icon name="lock" size="24px"></u-icon>
<u--input placeholder="請再次輸入密碼" border="bottom" v-model="confirmPassword" clearable :password="showPwd">
<template slot="suffix">
<view class="slot-list">
<u-icon :name="showPwd ? 'eye-off' : 'eye-fill'" @click="showPassword"
style="padding: 0 5px;"
></u-icon>
</view>
</template>
</u--input>
</u-form-item>
</u--form>
</view>
<view class="btn-list">
<u-button text="立即註冊" type="primary" size="large" @click="onSubmit"></u-button>
</view>
<u-radio-group v-model="agreeTerms" style="justify-content: center;align-items: center">
<u-radio shape="circle" name="1"></u-radio>
<span style="font-size: 12px">我已閱讀並同意
<span style="color: #3c9cff">《使用者協議》</span>和<span style="color: #3c9cff">《隱私協議》</span>
</span>
</u-radio-group>
<u-toast ref="uToast"></u-toast>
</view>
</template>
<script>
import {userAccountRegister} from '../../config/api.js'
export default {
data() {
return {
username: "",
password: "",
confirmPassword: "",
agreeTerms: 0,
showPwd: true,
}
},
methods: {
showPassword() {
this.showPwd = !this.showPwd
},
onSubmit() {
if (this.agreeTerms != 1) {
this.$refs.uToast.show({
message: '請先勾選同意使用者協議'
})
return
}
if (this.password !== this.confirmPassword) {
this.$refs.uToast.show({
message: '兩次輸入的密碼不一致'
})
return
}
userAccountRegister({
username: this.username,
password: this.password
}).then(() => {
this.$refs.uToast.show({
message: '註冊成功',
complete() {
// 跳轉登入
uni.navigateTo({
url: '/pages/index/index'
})
}
})
})
},
}
}
</script>
<style lang="scss">
.page-content {
display: flex;
flex-direction: column;
padding: 2rem 2rem;
}
.image-bg {
align-items: center;
}
.form-content {
padding: 1rem 0rem;
}
.slot-list {
display: flex;
flex-direction: row;
}
.btn-list {
display: flex;
flex-direction: column;
gap: 0.5rem;
padding-bottom: 1rem;
}
</style>
關於
我是一名獨立開發者,只工作不上班,帶你探索業界正流行的現代化全棧專案。
以下是近期會更新的一系列文章,歡迎關注~
- 使用者-登入註冊-後端
- 使用者-登入註冊-前端
- 使用者-錢包充值-後端
- 使用者-錢包充值-前端
- 營銷-簽到有禮-後端
- 營銷-簽到有禮-前端
- 營銷-簽到有禮-後端單元測試
- 營銷-限時秒殺-後端
- 營銷-限時秒殺-前端
- 營銷-優惠券-後端
- 營銷-優惠券-前端
本作品採用《CC 協議》,轉載必須註明作者和本文連結