• Vue中图片上传组件封装-antd的a-upload二次封装-案例


    a-upload组件

    api

    1. const publicApi = {
    2. UploadImage: '/common/uploadImage',
    3. DeleteImage: '/common/deleteImage',
    4. }
    5. /**
    6. * 上传图片
    7. * @param {*} parameter
    8. * @returns
    9. */
    10. export function UploadImage(parameter) {
    11. return request({
    12. url: publicApi.UploadImage,
    13. method: 'post',
    14. data: parameter
    15. })
    16. }
    17. /**
    18. * 删除图片 :name
    19. * @param {*} parameter
    20. * @returns
    21. */
    22. export function DeleteImage(parameter) {
    23. return request({
    24. url: `${publicApi.DeleteImage}/${parameter}`,
    25. method: 'delete'
    26. // params: parameter
    27. })
    28. }

    组件封装

    1. <template>
    2. <div class="upbase">
    3. <div v-show="progressVisible" class="progress-container">
    4. <div class="progress-bar">div>
    5. div>
    6. <a-upload
    7. v-if="!uploadType"
    8. :beforeUpload="beforeImageUpload"
    9. list-type="picture-card"
    10. :file-list="imageList"
    11. :multiple="multiple"
    12. :disabled="disabled"
    13. @change="handleImageChange"
    14. @preview="handlePreview"
    15. :custom-request="customRequest"
    16. >
    17. <div v-if="imageList.length < limitNum && !disabled">
    18. <a-icon type="plus" />
    19. <div class="ant-upload-text">上传div>
    20. div>
    21. a-upload>
    22. <a-upload
    23. v-else
    24. name="file"
    25. :file-list="imageList"
    26. :beforeUpload="beforeImageUpload"
    27. :multiple="multiple"
    28. :disabled="disabled"
    29. :custom-request="customRequest"
    30. @change="handleImageChange"
    31. >
    32. <div v-if="imageList.length < limitNum && !disabled">
    33. <a-button> <a-icon type="upload" /> 上传 a-button>
    34. div>
    35. a-upload>
    36. <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
    37. <img alt="example" style="width: 100%" :src="previewImage" />
    38. a-modal>
    39. div>
    40. template>
    41. <script>
    42. import { UploadImage, DeleteImage } from '@/api/public'
    43. function getBase64(file) {
    44. return new Promise((resolve, reject) => {
    45. const reader = new FileReader()
    46. reader.readAsDataURL(file)
    47. reader.onload = () => resolve(reader.result)
    48. reader.onerror = (error) => reject(error)
    49. })
    50. }
    51. function getName(url) {
    52. const list = url.split('/')
    53. return list[list.length - 1].split('.')[0]
    54. }
    55. export default {
    56. name: 'UpBase64',
    57. props: {
    58. defaultImageList: {
    59. type: Array,
    60. default: function () {
    61. return []
    62. },
    63. required: true,
    64. },
    65. // 组件展示样式
    66. uploadType: {
    67. type: Boolean,
    68. default: false,
    69. required: false,
    70. },
    71. // 文件类型列表
    72. fileTypeList: {
    73. type: Array,
    74. default: function () {
    75. return []
    76. },
    77. required: false,
    78. },
    79. // 容量大小
    80. limitSize: {
    81. type: Number,
    82. default: 2,
    83. required: false,
    84. },
    85. // 个数
    86. limitNum: {
    87. type: Number,
    88. default: 20,
    89. required: false,
    90. },
    91. // 是否支持多选
    92. multiple: {
    93. type: Boolean,
    94. default: false,
    95. required: false,
    96. },
    97. // 是否禁用
    98. disabled: {
    99. type: Boolean,
    100. default: false,
    101. required: false,
    102. },
    103. dwidth: {
    104. type: Number,
    105. default: 0,
    106. require: false,
    107. },
    108. dheight: {
    109. type: Number,
    110. default: 0,
    111. require: false,
    112. },
    113. },
    114. data() {
    115. return {
    116. previewVisible: false,
    117. progressVisible: false,
    118. progressValue: 10,
    119. previewImage: '',
    120. imageList: [],
    121. }
    122. },
    123. watch: {
    124. defaultImageList(newVal) {
    125. this.imageList = this.handleData(newVal)
    126. },
    127. },
    128. created() {
    129. this.imageList = this.handleData(this.defaultImageList)
    130. },
    131. methods: {
    132. // ---------------------------------------------img--start
    133. // 上传格式限制
    134. beforeImageUpload(file) {
    135. return new Promise((resolve, reject) => {
    136. if (this.fileTypeList.length != 0) {
    137. const index = this.fileTypeList.indexOf(file.type)
    138. if (index <= -1) {
    139. this.$message.error(`您只能上传${this.fileTypeList}文件`)
    140. return reject(new Error(`您只能上传${this.fileTypeList}文件,不能传${file.type}文件`))
    141. }
    142. }
    143. const limitSize = file.size / 1024 / 1024 < this.limitSize
    144. if (!limitSize) {
    145. this.$message.error(`文件大小不能大于${this.limitSize}MB`)
    146. return reject(new Error(`文件大小不能大于${this.limitSize}MB`))
    147. }
    148. const checkSize = this.checkImageWH(file, this.dwidth, this.dheight)
    149. return Promise.resolve(checkSize)
    150. .then(() => resolve())
    151. .catch((e) => {
    152. reject(e)
    153. })
    154. })
    155. },
    156. checkImageWH(file, width, height) {
    157. // 参数分别是上传的file,想要限制的宽,想要限制的高
    158. const that = this
    159. return new Promise(function (resolve, reject) {
    160. let filereader = new FileReader()
    161. filereader.onload = (e) => {
    162. let src = e.target.result
    163. const image = new Image()
    164. image.onload = function () {
    165. if ((width && this.width !== width) || (height && this.height !== height)) {
    166. // 上传图片的宽高与传递过来的限制宽高作比较,超过限制则调用失败回调
    167. const message = `图片宽高不满足,需要:宽 ${width || '不限制'},高 ${height || '不限制'}\n,当前图片宽:${
    168. this.width
    169. },高:${this.height}`
    170. that.$message.error(message)
    171. reject(new Error(message))
    172. } else {
    173. resolve({ width: this.width, height: this.height })
    174. }
    175. }
    176. image.onerror = reject
    177. image.src = src
    178. }
    179. filereader.readAsDataURL(file)
    180. })
    181. },
    182. async handlePreview(file) {
    183. if (!file.url && !file.preview) {
    184. file.preview = await getBase64(file.originFileObj)
    185. }
    186. this.previewImage = file.url || file.preview
    187. this.previewVisible = true
    188. },
    189. handleCancel() {
    190. this.previewVisible = false
    191. },
    192. // 自定义上传逻辑
    193. customRequest({ action, file, onSuccess, onError, onProgress }) {
    194. this.progressVisible = true
    195. new Promise((resolve) => {
    196. const fileReader = new FileReader()
    197. // 转化为base64
    198. fileReader.readAsDataURL(file)
    199. fileReader.onload = async () => {
    200. let index = {
    201. uid: this.genId(5),
    202. name: file.name,
    203. status: 'done',
    204. url: fileReader.result,
    205. }
    206. let params = {
    207. name: index.uid,
    208. data: index.url,
    209. }
    210. try {
    211. let res = await UploadImage(params)
    212. index.url = res.result.url
    213. if (res.status == 1) {
    214. setTimeout(() => {
    215. this.imageList = [...this.imageList.filter((item) => item.status === 'done'), index]
    216. this.$message.success('文件上传成功!')
    217. this.progressVisible = false
    218. this.handleChange()
    219. resolve(fileReader.result)
    220. }, 2000)
    221. } else {
    222. this.imageList = [...this.imageList.filter((item) => item.status === 'done')]
    223. this.$message.success(res.msg)
    224. this.handleChange()
    225. resolve(fileReader.result)
    226. }
    227. } catch (error) {
    228. console.log('upimg:', error)
    229. } finally {
    230. }
    231. }
    232. })
    233. },
    234. // 处理事件
    235. async handleImageChange(info) {
    236. try {
    237. // 删除图片
    238. let res = await DeleteImage(getName(info.file.url))
    239. console.log(res, 89)
    240. if (res.status == 1) {
    241. this.$message.success('删除成功!')
    242. } else {
    243. this.$message.error('删除失败!')
    244. }
    245. } catch (error) {
    246. // console.log('delimg:', error)
    247. } finally {
    248. let fileList = [...info.fileList]
    249. this.imageList = fileList
    250. this.handleChange()
    251. }
    252. },
    253. handleChange() {
    254. let index = this.imageList
    255. .filter((item) => item.url)
    256. .map((item) => {
    257. return item.url
    258. })
    259. // if (index?.length <= 0) return
    260. this.$emit('change', index ? index : [])
    261. },
    262. genId(length) {
    263. return Number(Math.random().toString().substr(3, length) + Date.now()).toString(36)
    264. },
    265. handleData(list) {
    266. return list.map((item) => {
    267. let index = this.genId(5)
    268. return {
    269. uid: index,
    270. name: index,
    271. status: 'done',
    272. url: item,
    273. }
    274. })
    275. },
    276. // ---------------------------------------------img--end
    277. },
    278. }
    279. script>
    280. <style lang="less" scoped>
    281. .ant-upload-select-picture-card i {
    282. font-size: 32px;
    283. color: #999;
    284. }
    285. .ant-upload-select-picture-card .ant-upload-text {
    286. margin-top: 8px;
    287. color: #666;
    288. }
    289. style>
    290. <style>
    291. .progress-container {
    292. width: 100px;
    293. height: 7px;
    294. background-color: #ffffff;
    295. border-radius: 5px;
    296. }
    297. .progress-bar {
    298. height: 100%;
    299. border-radius: 5px;
    300. animation-fill-mode: forwards;
    301. animation-name: progressBar;
    302. animation-iteration-count: infinite;
    303. background-color: #44cef6;
    304. animation-duration: 2s;
    305. animation-iteration-count: 1;
    306. }
    307. @keyframes progressBar {
    308. 0% {
    309. width: 0%;
    310. }
    311. 100% {
    312. width: 100%;
    313. }
    314. }
    315. style>

    使用

    1. <template>
    2. <page-header-wrapper>
    3. <div class="khdztps">
    4. <div class="container">
    5. <div class="left">
    6. <div class="wrap">
    7. <div class="title">
    8. <h2>客户端底图上传h2>
    9. div>
    10. <span class="tips">*上传格式为“.jpg 和.png“,大小不得超过1M,(375*665)span>
    11. <b-upload-image-base64
    12. ref="bUploadImageBase641"
    13. :limitNum="1"
    14. @change="imageChange($event, 'inviteBgImageList')"
    15. :defaultImageList="inviteBgImageList"
    16. :dwidth="375"
    17. :dheight="665"
    18. />
    19. div>
    20. <div class="wrap">
    21. <div class="title">
    22. <h2>客户端ICON替换h2>
    23. div>
    24. <span class="tips">*上传格式只能为“.png”,大小不得超过300k,(24*24)x3span>
    25. <div class="icon">
    26. <div class="wxz">
    27. <span class="title">未选中span>
    28. <div class="imgBox">
    29. <b-upload-image-base64
    30. ref="bUploadImageBase642"
    31. :limitNum="1"
    32. @change="imageChange($event, 'inviteHomeImageList')"
    33. :defaultImageList="inviteHomeImageList"
    34. :dwidth="24 * 3"
    35. :dheight="24 * 3"
    36. />
    37. div>
    38. div>
    39. div>
    40. div>
    41. div>
    42. div>
    43. <a-button type="primary" @click="saveSubmit">保存并预览a-button>
    44. div>
    45. page-header-wrapper>
    46. template>
    47. <script>
    48. import { commitCustomConfigure, queryCustomConfigure } from '@/api/feedback'
    49. import bUploadImageBase64 from '@/components/Plug/BUploadImageBase64.vue'
    50. export default {
    51. name: 'Khdztps',
    52. components: {
    53. bUploadImageBase64,
    54. },
    55. data() {
    56. return {
    57. inviteBgImageList: [],
    58. inviteHomeImageList: [],
    59. dataList: {
    60. BGUrl: '',
    61. HomeUrl: '',
    62. },
    63. }
    64. },
    65. created() {},
    66. mounted() {
    67. this.queryCustomConfigure()
    68. },
    69. methods: {
    70. saveSubmit() {
    71. this.commitCustomConfigure()
    72. },
    73. // 保存
    74. async commitCustomConfigure() {
    75. try {
    76. let res = await commitCustomConfigure(this.dataList)
    77. console.log(res, 89)
    78. if (res.status == 1) {
    79. this.$message.success('设置成功!')
    80. } else {
    81. this.$message.error(res.msg)
    82. }
    83. } catch (error) {
    84. console.log('sub:', error)
    85. }
    86. },
    87. // 获取 - 数据回填
    88. async queryCustomConfigure() {
    89. try {
    90. let res = await queryCustomConfigure()
    91. console.log(res, 89)
    92. if (res.status == 1) {
    93. // this.$message.success('成功!')
    94. this.dataList = res.result
    95. if (res.result.BGUrl) {
    96. this.inviteBgImageList.push(res.result.BGUrl)
    97. }
    98. if (res.result.HomeUrl) {
    99. this.inviteHomeImageList.push(res.result.HomeUrl)
    100. }
    101. } else {
    102. this.$message.error(res.msg)
    103. }
    104. } catch (error) {
    105. console.log('sub:', error)
    106. }
    107. },
    108. // 图片上传成功赋值
    109. imageChange(e, key) {
    110. console.log(e, key)
    111. switch (key) {
    112. // 图片
    113. case 'inviteBgImageList':
    114. this.dataList.BGUrl = e[0] || ''
    115. break
    116. case 'inviteHomeImageList':
    117. this.dataList.Unselect.Home = e[0] || ''
    118. break
    119. default:
    120. break
    121. }
    122. },
    123. },
    124. destroyed() {},
    125. activated() {},
    126. deactivated() {},
    127. }
    128. script>

  • 相关阅读:
    空间几何(点线面)知识整理
    闲鱼月收入10万的案例分享
    软件建模与分析
    2023年中国涂料用环氧树脂需求量及行业市场规模前景分析[图]
    Java中的多重继承问题
    excel 表格横向拼接(列拼接)
    【Ubuntu on windows】Package ‘xxxx‘ has no installation candidate
    react这几年重大意义的变化
    C 语言左移位操作在kernel驱动子系统中的特殊用途
    DigiCert代码签名证书
  • 原文地址:https://blog.csdn.net/JackieDYH/article/details/125677614