yl-frontend/src/views/ProfileView.vue

122 lines
2.9 KiB
Vue

<template>
<div class="profile-page">
<el-card class="profile-card">
<template #header>
<div class="card-header">
<span>个人信息</span>
<el-button type="primary" @click="handleEdit">编辑资料</el-button>
</div>
</template>
<div class="profile-content">
<div class="avatar-section">
<el-avatar :size="100" :src="userInfo.avatar" />
<el-upload
v-if="isEditing"
class="avatar-uploader"
action="/api/upload"
:show-file-list="false"
:on-success="handleAvatarSuccess"
>
<el-button size="small">更换头像</el-button>
</el-upload>
</div>
<el-form
:model="userInfo"
label-width="100px"
:disabled="!isEditing"
>
<el-form-item label="昵称">
<el-input v-model="userInfo.nickname" />
</el-form-item>
<el-form-item label="年龄">
<el-input-number v-model="userInfo.age" :min="1" :max="120" />
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="userInfo.gender">
<el-radio label="male">男</el-radio>
<el-radio label="female">女</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="手机号">
<el-input v-model="userInfo.phone" />
</el-form-item>
<el-form-item v-if="isEditing">
<el-button type="primary" @click="handleSave">保存</el-button>
<el-button @click="cancelEdit">取消</el-button>
</el-form-item>
</el-form>
</div>
</el-card>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { ElMessage } from 'element-plus'
const isEditing = ref(false)
const userInfo = reactive({
nickname: '张三',
age: 65,
gender: 'male',
phone: '13800138000',
avatar: 'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png'
})
const handleEdit = () => {
isEditing.value = true
}
const cancelEdit = () => {
isEditing.value = false
// TODO: 重置表单数据
}
const handleSave = async () => {
try {
// TODO: 调用API保存用户信息
ElMessage.success('保存成功')
isEditing.value = false
} catch (error) {
ElMessage.error('保存失败')
}
}
const handleAvatarSuccess = (response: any) => {
userInfo.avatar = response.url
ElMessage.success('头像上传成功')
}
</script>
<style scoped>
.profile-page {
padding: 20px;
}
.profile-card {
max-width: 800px;
margin: 0 auto;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.avatar-section {
text-align: center;
margin-bottom: 30px;
}
.avatar-uploader {
margin-top: 10px;
}
.profile-content {
padding: 20px;
}
</style>