avatarEdit.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. <template>
  2. <view class="f-straight wrapper">
  3. <uni-forms ref="form" :modelValue="formData" :rules="rules" validateTrigger="bind" label-width="105px" label-align="right">
  4. <uni-forms-item label="头像" name="avatar" class="f-straight" required>
  5. <view style="display: flex;flex-wrap: wrap;">
  6. <view class="upload-img" v-if="formData?.avatar">
  7. <uni-icons size="35" type="clear" color="#fe574a" style="position: absolute;right: -15px; top: -15px; z-index: 9" @click="formData.avatar = ''"></uni-icons>
  8. <image :src="formData?.avatar" mode="contain" style="width: 200rpx;height: 200rpx;" @click="handlePreviewImage"></image>
  9. </view>
  10. <view v-else class="upload-file" @click="uploadPhotos">
  11. <uni-icons type="plusempty" size="50" color="#f1f1f1"></uni-icons>
  12. </view>
  13. </view>
  14. </uni-forms-item>
  15. </uni-forms>
  16. </view>
  17. </template>
  18. <script setup>
  19. import { pathToBase64 } from '@/utils/image-tools.js'
  20. import { ref, watch } from 'vue'
  21. const props = defineProps({
  22. id: {
  23. type: String,
  24. default: ''
  25. },
  26. data: {
  27. type: String,
  28. default: ''
  29. }
  30. })
  31. const form = ref()
  32. const formData = ref({ avatar:'' })
  33. watch(
  34. () => props.data,
  35. (newVal) => {
  36. formData.value.avatar = newVal
  37. },
  38. { immediate: true },
  39. )
  40. // 图片预览
  41. const handlePreviewImage = () => {
  42. uni.previewImage({
  43. current: 0,
  44. urls: [formData.value.avatar]
  45. })
  46. }
  47. // 选择头像
  48. const uploadPhotos = () => {
  49. wx.chooseImage({
  50. count: 1,
  51. sizeType: ['original', 'compressed'],
  52. sourceType: ['album', 'camera'],
  53. async success(res) {
  54. console.log('res:', res)
  55. const size = res.tempFiles[0]?.size || 0
  56. if (size >= 31457280) {
  57. uni.showToast({
  58. icon: 'none',
  59. title: '头像上传大小不得超过 20MB !',
  60. duration: 2000
  61. })
  62. return
  63. }
  64. // 选取图片并转为base64
  65. formData.value.avatar = await pathToBase64(res.tempFilePaths[0])
  66. }
  67. })
  68. }
  69. const rules = {
  70. avatar:{
  71. rules: [{required: true, errorMessage: '请上传头像' }]
  72. }
  73. }
  74. const submit = async () => {
  75. return { id: props.id, data: formData.value.avatar}
  76. }
  77. defineExpose({
  78. id: props.id,
  79. submit
  80. })
  81. </script>
  82. <style lang="less" scoped>
  83. .wrapper{
  84. padding: 15px;
  85. padding-top: 30px;
  86. }
  87. .upload-img{
  88. position: relative;
  89. width: 200rpx;
  90. height: 200rpx;
  91. border: 1px solid #f1f1f1;
  92. margin: 10rpx;
  93. }
  94. .upload-file{
  95. width: 200rpx;
  96. height: 200rpx;
  97. border: 1px solid #f1f1f1;
  98. margin: 10rpx;
  99. display: flex;
  100. justify-content: center;
  101. align-items: center;
  102. border-radius: 10rpx;
  103. }
  104. </style>