上传文件
-
通过
uni.chooseMedia()
读取用户相册的照片或者拍照。 -
通过
uni.uploadFile()
上传用户图片。
<script setup lang="ts">
// ...省略
// 修改头像
const onAvatarChange = () => {
// 调用拍照/选择图片
uni.chooseMedia({
// 文件个数
count: 1,
// 文件类型
mediaType: ['image'],
success: (res) => {
// 本地路径
const { tempFilePath } = res.tempFiles[0]
// 文件上传
uni.uploadFile({
url: '/member/profile/avatar', // [!code ++]
name: 'file', // 后端数据字段名 // [!code ++]
filePath: tempFilePath, // 新头像 // [!code ++]
success: (res) => {
// 判断状态码是否上传成功
if (res.statusCode === 200) {
// 提取头像
const { avatar } = JSON.parse(res.data).result
// 当前页面更新头像
profile.value!.avatar = avatar // [!code ++]
// 更新 Store 头像
memberStore.profile!.avatar = avatar // [!code ++]
uni.showToast({ icon: 'success', title: '更新成功' })
} else {
uni.showToast({ icon: 'error', title: '出现错误' })
}
},
})
},
})
}
</script>
网页端上传文件用
Axios + FormData
小程序端上传文件用 wx.uploadFile()
使用 uni.uploadFile() 能自动多端兼容
小程序端需配置上传文件安全域名
更新表单
涉及到 <input>
、<radio>
、<picker>
表单组件的数据收集。
<input>
组件使用 v-model
收集数据,<radio-group>
组件使用 @change
事件收集数据。
<script setup lang="ts">
import type { Gender, ProfileDetail } from '@/types/member'
// 获取个人信息,修改个人信息需提供初始值 // [!code ++]
const profile = ref({} as ProfileDetail) // [!code ++]
const profile = ref<ProfileDetail>() // [!code --]
// 修改性别
const onGenderChange: UniHelper.RadioGroupOnChange = (ev) => {
profile.value.gender = ev.detail.value as Gender
}
</script>
<template>
<view class="viewport">
<!-- 表单 -->
<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>
<input class="input" type="text" placeholder="请填写职业" v-model="profile.profession" />
</view>
</view>
</view>
</view>
</template>
<picker>
组件使用 @change
事件收集数据。
<script setup lang="ts">
// 修改生日
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!
}
</script>
<template>
<view class="form-item">
<text class="label">生日</text>
<picker
class="picker"
mode="date"
start="1900-01-01"
:end="new Date()"
:value="profile.birthday"
@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
class="picker"
mode="region"
:value="profile.fullLocation?.split(' ')"
@change="onFullLocationChange"
>
<view v-if="profile.fullLocation">{{ profile.fullLocation }}</view>
<view class="placeholder" v-else>请选择城市</view>
</picker>
</view>
</template>