Newer
Older
DH_Apicture / src / views / system / user / profile / userAvatar.vue
@zhangqy zhangqy on 29 Nov 4 KB first commit
  1. <template>
  2. <div class="user-info-head" @click="editCropper()">
  3. <img :src="options.img" title="点击上传头像" class="img-circle img-lg" />
  4. <el-dialog :title="title" v-model="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog">
  5. <el-row>
  6. <el-col :xs="24" :md="12" :style="{ height: '350px' }">
  7. <vue-cropper
  8. ref="cropper"
  9. :img="options.img"
  10. :info="true"
  11. :autoCrop="options.autoCrop"
  12. :autoCropWidth="options.autoCropWidth"
  13. :autoCropHeight="options.autoCropHeight"
  14. :fixedBox="options.fixedBox"
  15. :outputType="options.outputType"
  16. @realTime="realTime"
  17. v-if="visible"
  18. />
  19. </el-col>
  20. <el-col :xs="24" :md="12" :style="{ height: '350px' }">
  21. <div class="avatar-upload-preview">
  22. <img :src="options.previews.url" :style="options.previews.img" />
  23. </div>
  24. </el-col>
  25. </el-row>
  26. <br />
  27. <el-row>
  28. <el-col :lg="2" :md="2">
  29. <el-upload action="#" :http-request="requestUpload" :show-file-list="false" :before-upload="beforeUpload">
  30. <el-button>
  31. 选择
  32. <el-icon class="el-icon--right"><Upload /></el-icon>
  33. </el-button>
  34. </el-upload>
  35. </el-col>
  36. <el-col :lg="{ span: 1, offset: 2 }" :md="2">
  37. <el-button icon="Plus" @click="changeScale(1)"></el-button>
  38. </el-col>
  39. <el-col :lg="{ span: 1, offset: 1 }" :md="2">
  40. <el-button icon="Minus" @click="changeScale(-1)"></el-button>
  41. </el-col>
  42. <el-col :lg="{ span: 1, offset: 1 }" :md="2">
  43. <el-button icon="RefreshLeft" @click="rotateLeft()"></el-button>
  44. </el-col>
  45. <el-col :lg="{ span: 1, offset: 1 }" :md="2">
  46. <el-button icon="RefreshRight" @click="rotateRight()"></el-button>
  47. </el-col>
  48. <el-col :lg="{ span: 2, offset: 6 }" :md="2">
  49. <el-button type="primary" @click="uploadImg()">提 交</el-button>
  50. </el-col>
  51. </el-row>
  52. </el-dialog>
  53. </div>
  54. </template>
  55.  
  56. <script setup>
  57. import 'vue-cropper/dist/index.css';
  58. import { VueCropper } from 'vue-cropper';
  59. import { uploadAvatar } from '@/api/user';
  60. import useUserStore from '@/store/modules/user';
  61.  
  62. const userStore = useUserStore();
  63. const { proxy } = getCurrentInstance();
  64.  
  65. const open = ref(false);
  66. const visible = ref(false);
  67. const title = ref('修改头像');
  68.  
  69. //图片裁剪数据
  70. const options = reactive({
  71. img: userStore.avatar, // 裁剪图片的地址
  72. autoCrop: true, // 是否默认生成截图框
  73. autoCropWidth: 200, // 默认生成截图框宽度
  74. autoCropHeight: 200, // 默认生成截图框高度
  75. fixedBox: true, // 固定截图框大小 不允许改变
  76. outputType: 'png', // 默认生成截图为PNG格式
  77. previews: {}, //预览数据
  78. });
  79.  
  80. /** 编辑头像 */
  81. function editCropper() {
  82. open.value = true;
  83. }
  84. /** 打开弹出层结束时的回调 */
  85. function modalOpened() {
  86. visible.value = true;
  87. }
  88. /** 覆盖默认上传行为 */
  89. function requestUpload() {}
  90. /** 向左旋转 */
  91. function rotateLeft() {
  92. proxy.$refs.cropper.rotateLeft();
  93. }
  94. /** 向右旋转 */
  95. function rotateRight() {
  96. proxy.$refs.cropper.rotateRight();
  97. }
  98. /** 图片缩放 */
  99. function changeScale(num) {
  100. num = num || 1;
  101. proxy.$refs.cropper.changeScale(num);
  102. }
  103. /** 上传预处理 */
  104. function beforeUpload(file) {
  105. if (file.type.indexOf('image/') == -1) {
  106. proxy.$modal.msgError('文件格式错误,请上传图片类型,如:JPG,PNG后缀的文件。');
  107. } else {
  108. const reader = new FileReader();
  109. reader.readAsDataURL(file);
  110. reader.onload = () => {
  111. options.img = reader.result;
  112. };
  113. }
  114. }
  115. /** 上传图片 */
  116. function uploadImg() {
  117. proxy.$refs.cropper.getCropBlob(data => {
  118. let formData = new FormData();
  119. formData.append('avatarfile', data);
  120. uploadAvatar(formData).then(response => {
  121. open.value = false;
  122. options.img = response.data;
  123. userStore.avatar = options.img;
  124. proxy.$modal.msgSuccess('修改成功');
  125. visible.value = false;
  126. });
  127. });
  128. }
  129. /** 实时预览 */
  130. function realTime(data) {
  131. options.previews = data;
  132. }
  133. /** 关闭窗口 */
  134. function closeDialog() {
  135. options.img = userStore.avatar;
  136. options.visible = false;
  137. }
  138. </script>
  139.  
  140. <style lang="scss" scoped>
  141. .user-info-head {
  142. position: relative;
  143. display: inline-block;
  144. height: 120px;
  145. }
  146.  
  147. .user-info-head:hover:after {
  148. content: '+';
  149. position: absolute;
  150. left: 0;
  151. right: 0;
  152. top: 0;
  153. bottom: 0;
  154. color: #eee;
  155. background: rgba(0, 0, 0, 0.5);
  156. font-size: 24px;
  157. font-style: normal;
  158. -webkit-font-smoothing: antialiased;
  159. -moz-osx-font-smoothing: grayscale;
  160. cursor: pointer;
  161. line-height: 110px;
  162. border-radius: 50%;
  163. }
  164. </style>