uniapp实战 -- 个人信息维护(含选择图片 uni.chooseMedia,上传文件 uni.uploadFile,获取和更新表单数据)

本文主要是介绍uniapp实战 -- 个人信息维护(含选择图片 uni.chooseMedia,上传文件 uni.uploadFile,获取和更新表单数据),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

效果预览

在这里插入图片描述

在这里插入图片描述

相关代码

页面–我的

src\pages\my\my.vue

    <!-- 个人资料 --><view class="profile" :style="{ paddingTop: safeAreaInsets!.top + 'px' }"><!-- 情况1:已登录 --><view class="overview" v-if="memberStore.profile"><navigator url="/pagesMember/profile/profile" hover-class="none"><image class="avatar" mode="aspectFill" :src="memberStore.profile.avatar"></image></navigator><view class="meta"><view class="nickname">{{ memberStore.profile.nickname || memberStore.profile.account }}</view><navigator class="extra" url="/pagesMember/profile/profile" hover-class="none"><text class="update">更新头像昵称</text></navigator></view></view><!-- 情况2:未登录 --><view class="overview" v-else><navigator url="/pages/login/login" hover-class="none"><imageclass="avatar gray"mode="aspectFill"src="http://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-04-06/db628d42-88a7-46e7-abb8-659448c33081.png"></image></navigator><view class="meta"><navigator url="/pages/login/login" hover-class="none" class="nickname">未登录</navigator><view class="extra"><text class="tips">点击登录账号</text></view></view></view><navigator class="settings" url="/pagesMember/settings/settings" hover-class="none">设置</navigator></view>
/* 用户信息 */
.profile {margin-top: 20rpx;position: relative;.overview {display: flex;height: 120rpx;padding: 0 36rpx;color: #fff;}.avatar {width: 120rpx;height: 120rpx;border-radius: 50%;background-color: #eee;}.gray {filter: grayscale(100%);}.meta {display: flex;flex-direction: column;justify-content: center;align-items: flex-start;line-height: 30rpx;padding: 16rpx 0;margin-left: 20rpx;}.nickname {max-width: 350rpx;margin-bottom: 16rpx;font-size: 30rpx;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;}.extra {display: flex;font-size: 20rpx;}.tips {font-size: 22rpx;}.update {padding: 3rpx 10rpx 1rpx;color: rgba(255, 255, 255, 0.8);border: 1rpx solid rgba(255, 255, 255, 0.8);margin-right: 10rpx;border-radius: 30rpx;}.settings {position: absolute;bottom: 0;right: 40rpx;font-size: 30rpx;color: #fff;}
}
// 获取屏幕边界到安全区域距离
const { safeAreaInsets } = uni.getSystemInfoSync()import { useMemberStore } from '@/stores'// 获取会员信息
const memberStore = useMemberStore()

页面–个人信息维护

src\pagesMember\profile\profile.vue

<script setup lang="ts">
import { getMemberProfileAPI, putMemberProfileAPI } from '@/apis/profile'
import type { Gender, ProfileDetail } from '@/types/member'
import { onLoad } from '@dcloudio/uni-app'
import { ref } from 'vue'// 获取屏幕边界到安全区域距离
const { safeAreaInsets } = uni.getSystemInfoSync()// 获取个人信息,修改个人信息需提供初始值 (使用 as 进行类型断言,不用再声明类型)
const profile = ref({} as ProfileDetail)
const getMemberProfileData = async () => {const res = await getMemberProfileAPI()profile.value = res.result
}onLoad(() => {getMemberProfileData()
})import { useMemberStore } from '@/stores'// 获取会员信息
const memberStore = useMemberStore()// 修改头像
const onAvatarChange = () => {// 调用拍照/选择图片uni.chooseMedia({// 文件个数count: 1,// 文件类型mediaType: ['image'],success: (res) => {// 本地路径const { tempFilePath } = res.tempFiles[0]// 文件上传uni.uploadFile({url: '/member/profile/avatar',name: 'file', // 后端数据字段名filePath: tempFilePath, // 新头像success: (res) => {// 判断状态码是否上传成功if (res.statusCode === 200) {// 提取头像const { avatar } = JSON.parse(res.data).result// 当前页面更新头像profile.value!.avatar = avatar// 更新 Store 头像memberStore.profile!.avatar = avataruni.showToast({ icon: 'success', title: '更新成功' })} else {uni.showToast({ icon: 'error', title: '出现错误' })}},})},})
}// 修改性别
const onGenderChange: UniHelper.RadioGroupOnChange = (ev) => {profile.value.gender = ev.detail.value as Gender
}// 修改生日
const onBirthdayChange: UniHelper.DatePickerOnChange = (ev) => {profile.value.birthday = ev.detail.value
}// 修改城市
let fullLocationCode: [string, string, string] = ['', '', '']
const onFullLocationChange: UniHelper.RegionPickerOnChange = (ev) => {// 修改前端界面profile.value.fullLocation = ev.detail.value.join(' ')// 提交后端更新fullLocationCode = ev.detail.code!
}// 点击保存提交表单
const onSubmit = async () => {const { nickname, gender, birthday, profession } = profile.valueconst res = await putMemberProfileAPI({nickname,gender,birthday,profession,provinceCode: fullLocationCode[0],cityCode: fullLocationCode[1],countyCode: fullLocationCode[2],})// 更新Store昵称memberStore.profile!.nickname = res.result.nicknameuni.showToast({ icon: 'success', title: '保存成功' })setTimeout(() => {uni.navigateBack()}, 400)
}
</script><template><view class="viewport"><!-- 导航栏 --><view class="navbar" :style="{ paddingTop: safeAreaInsets?.top + 'px' }"><navigator open-type="navigateBack" class="back icon-left" hover-class="none"></navigator><view class="title">个人信息</view></view><!-- 头像 --><view class="avatar"><view class="avatar-content" @tap="onAvatarChange"><image class="image" :src="profile?.avatar" mode="aspectFill" /><text class="text">点击修改头像</text></view></view><!-- 表单 --><view class="form"><!-- 表单内容 --><view class="form-content"><view class="form-item"><text class="label">账号</text><text class="account">{{ profile?.account }}</text></view><view class="form-item"><text class="label">昵称</text><input class="input" type="text" placeholder="请填写昵称" v-model="profile.nickname" /></view><view class="form-item"><text class="label">性别</text><radio-group @change="onGenderChange"><label class="radio"><radio value="" color="#27ba9b" :checked="profile?.gender === '男'" /></label><label class="radio"><radio value="" color="#27ba9b" :checked="profile?.gender === '女'" /></label></radio-group></view><view class="form-item"><text class="label">生日</text><pickerclass="picker"mode="date":value="profile?.birthday"start="1900-01-01":end="new Date()"@change="onBirthdayChange"><view v-if="profile?.birthday">{{ profile?.birthday }}</view><view class="placeholder" v-else>请选择日期</view></picker></view><view class="form-item"><text class="label">城市</text><picker@change="onFullLocationChange"class="picker":value="profile?.fullLocation?.split(' ')"mode="region"><view v-if="profile?.fullLocation">{{ profile.fullLocation }}</view><view class="placeholder" v-else>请选择城市</view></picker></view><view class="form-item"><text class="label">职业</text><input class="input" type="text" placeholder="请填写职业" v-model="profile.profession" /></view></view><!-- 提交按钮 --><button class="form-button" @tap="onSubmit">保 存</button></view></view>
</template>
<style lang="scss">
page {background-color: #f4f4f4;
}.viewport {display: flex;flex-direction: column;height: 100%;background-image: url(https://pcapi-xiaotuxian-front-devtest.itheima.net/miniapp/images/order_bg.png);background-size: auto 420rpx;background-repeat: no-repeat;
}// 导航栏
.navbar {position: relative;.title {height: 40px;display: flex;justify-content: center;align-items: center;font-size: 16px;font-weight: 500;color: #fff;}.back {position: absolute;height: 40px;width: 40px;left: 0;font-size: 20px;color: #fff;display: flex;justify-content: center;align-items: center;}
}// 头像
.avatar {text-align: center;width: 100%;height: 260rpx;display: flex;flex-direction: column;justify-content: center;align-items: center;.image {width: 160rpx;height: 160rpx;border-radius: 50%;background-color: #eee;}.text {display: block;padding-top: 20rpx;line-height: 1;font-size: 26rpx;color: #fff;}
}// 表单
.form {background-color: #f4f4f4;&-content {margin: 20rpx 20rpx 0;padding: 0 20rpx;border-radius: 10rpx;background-color: #fff;}&-item {display: flex;height: 96rpx;line-height: 46rpx;padding: 25rpx 10rpx;background-color: #fff;font-size: 28rpx;border-bottom: 1rpx solid #ddd;&:last-child {border: none;}.label {width: 180rpx;color: #333;}.account {color: #666;}.input {flex: 1;display: block;height: 46rpx;}.radio {margin-right: 20rpx;}.picker {flex: 1;}.placeholder {color: #808080;}}&-button {height: 80rpx;text-align: center;line-height: 80rpx;margin: 30rpx 20rpx;color: #fff;border-radius: 80rpx;font-size: 30rpx;background-color: #27ba9b;}
}
</style>

接口

src\apis\profile.ts

import type { ProfileDetail, ProfileParams } from '@/types/member'
import { http } from '@/utils/http'/*** 获取个人信息*/
export const getMemberProfileAPI = () => {return http<ProfileDetail>({method: 'GET',url: '/member/profile',})
}/*** 修改个人信息* @param data 请求体参数*/
export const putMemberProfileAPI = (data: ProfileParams) => {return http<ProfileDetail>({method: 'PUT',url: '/member/profile',data,})
}

类型声明

src\types\member.d.ts

/** 封装通用信息 */
type BaseProfile = {/** 用户ID */id: number/** 头像  */avatar: string/** 账户名  */account: string/** 昵称 */nickname?: string
}/** 小程序登录 登录用户信息 */
export type LoginResult = BaseProfile & {/** 用户ID */id: number/** 头像  */avatar: string/** 账户名  */account: string/** 昵称 */nickname?: string/** 手机号 */mobile: string/** 登录凭证 */token: string
}/** 个人信息 用户详情信息 */
export type ProfileDetail = BaseProfile & {/** 性别 */gender?: Gender/** 生日 */birthday?: string/** 省市区 */fullLocation?: string/** 职业 */profession?: string
}
/** 性别 */
export type Gender = '女' | '男'/** 个人信息 修改请求体参数 */
export type ProfileParams = Pick<ProfileDetail,'nickname' | 'gender' | 'birthday' | 'profession'
> & {/** 省份编码 */provinceCode?: string/** 城市编码 */cityCode?: string/** 区/县编码 */countyCode?: string
}

持久化本地存储 store

src\stores\index.ts

import { createPinia } from 'pinia'
import persist from 'pinia-plugin-persistedstate'// 创建 pinia 实例
const pinia = createPinia()
// 使用持久化存储插件
pinia.use(persist)// 默认导出,给 main.ts 使用
export default pinia// 模块统一导出
export * from './modules/member'

src\stores\modules\member.ts

import { defineStore } from 'pinia'
import { ref } from 'vue'// 定义 Store
export const useMemberStore = defineStore('member',() => {// 会员信息const profile = ref<any>()// 保存会员信息,登录时使用const setProfile = (val: any) => {profile.value = val}// 清理会员信息,退出时使用const clearProfile = () => {profile.value = undefined}// 记得 returnreturn {profile,setProfile,clearProfile,}},// 持久化{persist: {// 调整为兼容多端的APIstorage: {setItem(key, value) {uni.setStorageSync(key, value)},getItem(key) {return uni.getStorageSync(key)},},},},
)

这篇关于uniapp实战 -- 个人信息维护(含选择图片 uni.chooseMedia,上传文件 uni.uploadFile,获取和更新表单数据)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/525403

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

如何选择适合孤独症兄妹的学校?

在探索适合孤独症儿童教育的道路上,每一位家长都面临着前所未有的挑战与抉择。当这份责任落在拥有孤独症兄妹的家庭肩上时,选择一所能够同时满足两个孩子特殊需求的学校,更显得尤为关键。本文将探讨如何为这样的家庭做出明智的选择,并介绍星贝育园自闭症儿童寄宿制学校作为一个值得考虑的选项。 理解孤独症儿童的独特性 孤独症,这一复杂的神经发育障碍,影响着儿童的社交互动、沟通能力以及行为模式。对于拥有孤独症兄

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

Hadoop集群数据均衡之磁盘间数据均衡

生产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。(Hadoop3.x新特性) plan后面带的节点的名字必须是已经存在的,并且是需要均衡的节点。 如果节点不存在,会报如下错误: 如果节点只有一个硬盘的话,不会创建均衡计划: (1)生成均衡计划 hdfs diskbalancer -plan hadoop102 (2)执行均衡计划 hd

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传