应无所住,而生其心
排名
1
文章
860
粉丝
112
评论
163
net core webapi post传递参数
庸人 : 确实坑哈,我也是下班好了好几次,发现后台传递对象是可以的,但...
百度编辑器自定义模板
庸人 : 我建议换个编辑器,因为现在百度富文本已经停止维护了,用tinymec...
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术

uniapp 微信小程序 上传图片,上传文件,上传视频等,上传组件封装

1765人阅读 2024/7/26 16:27 总访问:5182718 评论:0 收藏:0 手机
分类: 前端


上传图片文件还可以参考:https://www.tnblog.net/aojiancc2/article/details/8233 这个里边有关于.net6实现图片上传后端的

然后后台图片文件存储是自己搭建图片服务minio

实现的效果

上传图片之前的效果:

上传图片之后的效果:

封装的上传组件

  1. <!--
  2. 项目:图片上传插件
  3. 备注:接口的返回值是否符合插件所写的code=0,如果不是请复制 upload 和 asyncUpload 查找该方法 在注释的地方修改。
  4. -->
  5. <template>
  6. <view class="w-100 imgupload">
  7. <view class="w-100 flex_wrap">
  8. <view :class="single ? 'single-css' : 'imgs-view'" v-for="(v, i) in imgArray" :key="i">
  9. <image @click="preview(v, i)" :src="v.url"></image>
  10. <view v-if="!disabled" :class="conf.style ? 'del-btn-style-' + conf.style : 'del-btn'" @click="delImg(i)">
  11. <image v-if="conf.delIcon" :src="conf.delIcon"></image>
  12. <text v-if="!conf.delIcon && conf.style == 1" class="icon_upload">&#xe785;</text>
  13. <text v-if="!conf.delIcon && conf.style == 2" class="icon_upload">&#xe785;</text>
  14. </view>
  15. <view class="uploading flex_xy_center" :class="single ? 'single-css' : 'imgs-view'"
  16. v-if="!v.upload && loading && startUpload">
  17. <view>
  18. <image v-if="conf.loadIcon" :src="conf.loadIcon"></image>
  19. <text v-if="!conf.loadIcon && conf.style == 1" class="icon_upload">&#xe6a0;</text>
  20. <text v-if="!conf.loadIcon && conf.style == 2" class="icon_upload">&#xe616;</text>
  21. <view class="upload-txt">{{ conf.loadText || '上传中...' }}</view>
  22. </view>
  23. </view>
  24. <view class="result" v-if="!conf.style && conf.resultTip && v.upload">
  25. <label class="success" v-if="v.result === true">上传成功</label>
  26. <label class="error" v-if="v.result === false">上传失败({{ v.msg }})</label>
  27. </view>
  28. <view v-if="conf.style == 1 && conf.resultTip && v.upload && !disabled" class="result-style"
  29. :class="'result-' + (v.result ? 1 : 2)">
  30. <view v-if="v.result == true"><text class="icon_upload">&#xe666;</text>上传成功</view>
  31. <view v-if="v.result == false"><text class="icon_upload">&#xe785;</text>上传失败({{
  32. v.msg
  33. }})</view>
  34. </view>
  35. </view>
  36. <view v-if="imgArray.length < imgCount && !disabled" :style="conf.borderStyle" class="flex_xy_center"
  37. :class="single ? 'single-add' : 'upload-img-view'" @click="upPhoto">
  38. <text v-if="conf.addStyle == '1'" class="icon_upload">&#xe615;</text>
  39. <text v-if="conf.addStyle == '2'" class="icon_upload add">&#xe606;</text>
  40. </view>
  41. </view>
  42. <view v-if="!closeTip && !tipObj.prompt" class="imgupload__tip">* 最多上传{{ imgCount }}张图片(<label> {{ imgArray.length }}
  43. </label>/{{
  44. imgCount
  45. }})</view>
  46. <view class="imgupload__tip" :style="{ color: tipObj.typeColor }" v-show="tipObj.prompt || tipObj.must">{{
  47. tipObj.prompt }}
  48. </view>
  49. <button open-type="agreePrivacyAuthorization"></button>
  50. </view>
  51. </template>
  52. <script>
  53. // 图片压缩
  54. import { compressAccurately } from 'image-conversion'
  55. export default {
  56. name: 'imgUpload',
  57. props: {
  58. baseUrl: {
  59. type: String,
  60. default: ''
  61. },
  62. imgArr: {
  63. //图片数组
  64. type: [Array]
  65. },
  66. uploadImgCount: {
  67. //一次上传图片数
  68. type: String,
  69. default: '3'
  70. },
  71. imgCount: {
  72. //可上传图片总数
  73. type: String,
  74. default: '3'
  75. },
  76. imgSize: {
  77. //图片大小 单位M
  78. type: Number,
  79. default: 2
  80. },
  81. disabled: {
  82. //禁用
  83. type: Boolean,
  84. default: false
  85. },
  86. formData: {
  87. type: Object,
  88. default: function () {
  89. return {}
  90. }
  91. },
  92. imgType: {
  93. //如果是小程序,这个值则没用作用
  94. type: [Array],
  95. default: function () {
  96. return ['jpeg', 'png', 'jpg']
  97. }
  98. },
  99. single: {
  100. //只上传一张图片
  101. type: Boolean,
  102. default: false
  103. },
  104. closeTip: {
  105. type: Boolean,
  106. default: false
  107. },
  108. loading: {
  109. type: Boolean,
  110. default: true
  111. },
  112. url: {
  113. //上传图片Url
  114. type: String
  115. },
  116. async: {
  117. type: Boolean,
  118. default: false
  119. },
  120. header: {
  121. type: Array,
  122. default: function () {
  123. return []
  124. }
  125. },
  126. previewMany: {
  127. //多图预览
  128. type: Boolean,
  129. default: false
  130. },
  131. pressImg: {
  132. //压缩图片 H5暂不支持压缩api
  133. type: Number,
  134. default: -1
  135. },
  136. config: {
  137. type: Object,
  138. default: function () {
  139. return {}
  140. }
  141. },
  142. beforUploadHandle: {
  143. type: Function,
  144. default: () => {
  145. new Promise()
  146. }
  147. }
  148. },
  149. data() {
  150. return {
  151. sysInfo: {},
  152. imgArray: [],
  153. canUpCount: '',
  154. startUpload: false,
  155. tipObj: {
  156. prompt: '',
  157. typeColor: '#009100',
  158. must: false, //必须要存在的时候
  159. success: '#009100', //成功-#009100; 可自定义修改
  160. // warning: '#bb9300', // 警告 -#bb9300; 可自定义修改
  161. error: '#FF0000', // 失败--#FF0000; 可自定义修改
  162. warning: '#FF0000'
  163. },
  164. conf: {
  165. delIcon: '', //删除图片icon
  166. resultTip: true, //结果提示
  167. style: '1', //组件默认风格
  168. loadIcon: '', //加载时的图标
  169. loadText: '', //加载时的文字
  170. borderStyle: 'border:2rpx dotted #dadada',
  171. addStyle: '2' //添加风格 1 图片标 2 加号标
  172. },
  173. headers: {},
  174. curPlatform: '',
  175. currIndex: null
  176. }
  177. },
  178. created() {
  179. this.getSysInfo()
  180. this.imgArray = this.imgArr || []
  181. this.changeImgArr(true)
  182. this.canUpCount = this.single ? 1 : Number(this.uploadImgCount)
  183. if (this.url) {
  184. this.tipObj.prompt = ''
  185. } else {
  186. this.tipObj.prompt = '你没有传入上传url,请检查传入参数'
  187. this.tipObj.typeColor = this.tipObj.error
  188. }
  189. this.changeHeader(this.header)
  190. // 参数合并
  191. this.conf = Object.assign(this.conf, this.config)
  192. },
  193. watch: {
  194. imgArr(n, o) {
  195. this.imgArray = n || []
  196. this.changeImgArr(true)
  197. },
  198. imgCount(n, o) {
  199. this.uploadImgCount = n
  200. this.canUpCount = this.single ? 1 : Number(this.uploadImgCount)
  201. },
  202. url(n, o) {
  203. if (n) {
  204. this.tipObj.prompt = ''
  205. } else {
  206. this.tipObj.prompt = '你没有传入上传url,请检查传入参数'
  207. this.tipObj.typeColor = this.tipObj.error
  208. }
  209. },
  210. header(n, o) {
  211. this.changeHeader(n)
  212. },
  213. config(n, o) {
  214. this.conf = Object.assign(this.conf, this.config)
  215. }
  216. },
  217. methods: {
  218. upPhoto() {
  219. let that = this
  220. that.beforUploadHandle().then(() => {
  221. if (!that.url) {
  222. that.tipObj.prompt = '你没有传入上传url,请检查!'
  223. that.tipObj.typeColor = that.tipObj.error
  224. return
  225. }
  226. if (
  227. Number(that.imgCount - that.imgArray.length) <
  228. Number(that.uploadImgCount)
  229. ) {
  230. that.canUpCount = Number(that.imgCount - that.imgArray.length)
  231. }
  232. if (!that.tipObj.must) {
  233. that.tipObj.prompt = ''
  234. }
  235. that.tipObj.must = false
  236. uni.showActionSheet({
  237. itemList: ['拍照上传', '从相册中选择'],
  238. success: function (res) {
  239. if (res.tapIndex == 0) {
  240. uni.chooseMedia({
  241. count: Number(that.canUpCount),
  242. sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
  243. sourceType: ['camera'], //从相册选择
  244. success: function (res) {
  245. const addImgArray = []
  246. console.log(res.tempFiles)
  247. if (res) {
  248. if (res.tempFiles) {
  249. for (let item of res.tempFiles) {
  250. if (item.size > that.imgSize * 1024 * 1024) {
  251. uni.showToast({
  252. title: `图片不能大于${that.imgSize}M`,
  253. icon: 'none'
  254. })
  255. return false
  256. }
  257. if (item.type) {
  258. let r = that.imgType.some((v) => {
  259. let type = item.type.split('/')
  260. if (type.length) return v === type[1]
  261. })
  262. if (!r) {
  263. uni.showToast({
  264. title: `只允许上传${that.imgType}的类型`,
  265. icon: 'none'
  266. })
  267. return false
  268. }
  269. }
  270. addImgArray.push({ url: item.tempFilePath })
  271. }
  272. }
  273. that.currIndex = that.imgArray.length
  274. that.imgArray = [...that.imgArray, ...addImgArray]
  275. console.log(that.imgArray)
  276. // that.changeImgArr(false);
  277. if (that.pressImg >= 0) {
  278. //存在图片压缩 开启图片压缩
  279. if (that.checkPlatform()) {
  280. // H5环境下不支持
  281. that.pressImages()
  282. }
  283. } else {
  284. //正常异步提交
  285. that.hasAysnc()
  286. }
  287. }
  288. }
  289. })
  290. } else if (res.tapIndex == 1) {
  291. uni.chooseMedia({
  292. count: Number(that.canUpCount),
  293. sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
  294. sourceType: ['album'], //从相册选择
  295. success: function (res) {
  296. const addImgArray = []
  297. if (res) {
  298. console.log(res.tempFiles)
  299. if (res.tempFiles) {
  300. for (let item of res.tempFiles) {
  301. if (item.size > that.imgSize * 1024 * 1024) {
  302. uni.showToast({
  303. title: `图片不能大于${that.imgSize}M`,
  304. icon: 'none'
  305. })
  306. return false
  307. }
  308. if (item.type) {
  309. let r = that.imgType.some((v) => {
  310. let type = item.type.split('/')
  311. if (type.length) return v === type[1]
  312. })
  313. if (!r) {
  314. uni.showToast({
  315. title: `只允许上传${that.imgType}的类型`,
  316. icon: 'none'
  317. })
  318. return false
  319. }
  320. }
  321. addImgArray.push({ url: item.tempFilePath })
  322. }
  323. }
  324. that.currIndex = that.imgArray.length
  325. that.imgArray = [...that.imgArray, ...addImgArray]
  326. console.log(that.imgArray)
  327. // that.changeImgArr(false);
  328. if (that.pressImg >= 0) {
  329. //存在图片压缩 开启图片压缩
  330. if (that.checkPlatform()) {
  331. // H5环境下不支持
  332. that.pressImages()
  333. }
  334. } else {
  335. //正常异步提交
  336. that.hasAysnc()
  337. }
  338. }
  339. },
  340. fail: function (res) {
  341. console.log(res)
  342. }
  343. })
  344. }
  345. },
  346. fail: function (res) {
  347. console.log(res.errMsg)
  348. }
  349. })
  350. })
  351. },
  352. preview(obj, index) {
  353. if (this.previewMany) {
  354. let urls = []
  355. urls.push(obj.url)
  356. this.imgArray.map((item) => {
  357. if (obj.id != item.id) {
  358. urls.push(item.url)
  359. }
  360. })
  361. uni.previewImage({
  362. urls: urls
  363. })
  364. } else {
  365. // 预览图片(单张)
  366. uni.previewImage({
  367. urls: [obj.url]
  368. })
  369. }
  370. },
  371. changeImgArr(type) {
  372. for (let index in this.imgArray) {
  373. let item = this.imgArray[index]
  374. if (!item.upload) {
  375. if (item.upload === false) {
  376. this.imgArray[index].url = item.url
  377. } else {
  378. this.imgArray[index] = {
  379. id: item.id,
  380. upload: type,
  381. url: item.url,
  382. result: type
  383. }
  384. }
  385. }
  386. }
  387. },
  388. pressImages() {
  389. const _this = this
  390. let success = 0
  391. let completeNum = 0
  392. for (let item of _this.imgArray) {
  393. uni.compressImage({
  394. src: item.url,
  395. quality: _this.pressImg,
  396. success: (res) => {
  397. ++success
  398. item.pressUrl = res.tempFilePath
  399. },
  400. error: (res) => {
  401. console.log(res)
  402. },
  403. complete: (res) => {
  404. ++completeNum
  405. //等待全部压缩完成
  406. if (completeNum === _this.imgArray.length) {
  407. console.log(success)
  408. if (success >= _this.imgArray.length) {
  409. _this.tipObj.prompt = '全部压缩成功!'
  410. _this.tipObj.typeColor = _this.tipObj.success
  411. } else {
  412. let errorNum = _this.imgArray.length - success
  413. _this.tipObj.prompt = `${errorNum}个文件压缩失败`
  414. _this.tipObj.typeColor = _this.tipObj.warning
  415. }
  416. console.log('res', _this.imgArray)
  417. if (_this.async) {
  418. //直接上传
  419. _this.asyncUpload()
  420. }
  421. }
  422. }
  423. })
  424. }
  425. },
  426. asyncUpload() {
  427. const _this = this
  428. if (_this.imgArray.length) {
  429. let length = _this.imgArray.length
  430. _this.startUpload = true
  431. _this.tipObj.prompt = ''
  432. let result = []
  433. //_this.currIndex;
  434. for (let i = 0; i < length; i++) {
  435. let item = _this.imgArray[i]
  436. console.log(item)
  437. let subUrl = _this.pressImg >= 0 ? item.pressUrl : item.url
  438. if (!item.upload) {
  439. _this.asyncUploadMethod(subUrl, i, (res) => {
  440. if (res) {
  441. result.push(res)
  442. if (
  443. result.length == length ||
  444. length - _this.imgArr.length == result.length
  445. ) {
  446. if (_this.single) {
  447. _this.$emit('result', _this.imgArray[0])
  448. } else {
  449. console.log('list', _this.imgArray)
  450. _this.$emit('result', {
  451. all: _this.imgArray,
  452. new: result
  453. })
  454. }
  455. }
  456. }
  457. })
  458. }
  459. }
  460. }
  461. },
  462. asyncUploadMethod(url, i, callback) {
  463. const _this = this
  464. uni.uploadFile({
  465. url: _this.url,
  466. filePath: url,
  467. name: 'file',
  468. header: _this.headers,
  469. formData: _this.formData,
  470. success: (uploadFileRes) => {
  471. if (uploadFileRes.statusCode == 200) {
  472. let res = JSON.parse(uploadFileRes.data)
  473. /*注意 如果返回的结果字段不一样,请在这里做修改[res.code]*/
  474. if (res.code === 0 || res.code === '0') {
  475. //成功情况下
  476. _this.imgArray[i].result = true
  477. res.code = 0
  478. // _this.imgArray[i].url = res.url; //这里
  479. _this.imgArray[
  480. i
  481. ].url = `${_this.baseUrl}/oss/api/ImageViewer/${res.data.id}.jpg?percent=0.2&quality=80&od=false`
  482. _this.imgArray[i].id = res.data.id
  483. callback(res)
  484. } else {
  485. _this.imgArray[i].result = false
  486. _this.tipObj.prompt = '上传失败,请检查!'
  487. _this.tipObj.typeColor = _this.tipObj.error
  488. }
  489. } else {
  490. _this.imgArray[i].result = false
  491. }
  492. },
  493. fail: (e) => {
  494. _this.imgArray[i].result = false
  495. _this.tipObj.prompt = '上传失败,请检查!'
  496. _this.tipObj.typeColor = _this.tipObj.error
  497. console.log(e)
  498. },
  499. complete: () => {
  500. _this.imgArray[i].upload = true
  501. _this.startUpload = false
  502. _this.$forceUpdate()
  503. }
  504. })
  505. },
  506. delImg(i) {
  507. const _this = this
  508. uni.showModal({
  509. title: '提示',
  510. content: '是否删除这张照片?',
  511. success: function (res) {
  512. if (res.confirm) {
  513. const delImgInfo = _this.imgArray[i]
  514. _this.imgArray.splice(i, 1)
  515. if (_this.async) {
  516. _this.$emit('delImg', delImgInfo)
  517. }
  518. } else if (res.cancel) {
  519. }
  520. }
  521. })
  522. },
  523. upload(callback) {
  524. const _this = this
  525. if (!_this.async) {
  526. _this.tipObj.prompt = ''
  527. if (_this.imgArray.length) {
  528. this.startUpload = true
  529. let successNum = 0
  530. let urlArr = []
  531. for (let item of _this.imgArray) {
  532. _this.uploadImg(item, (res) => {
  533. /*注意 如果返回的结果字段不一样,请在这里做修改[res.code]*/
  534. if (res.code == 0) {
  535. successNum++
  536. urlArr.push(res.url) /*需要线上图片地址[res.fileVo]*/
  537. item.result = true
  538. } else {
  539. urlArr.push(res)
  540. item.result = false
  541. item.msg = res.Message
  542. }
  543. item.upload = true
  544. _this.$forceUpdate()
  545. _this.tipObj.prompt =
  546. '正在上传...(成功' + successNum + '张/' + urlArr.length + '张)'
  547. _this.tipObj.typeColor = _this.tipObj.success
  548. if (urlArr.length == _this.imgArray.length) {
  549. _this.tipObj.prompt = '已全部上传完成!'
  550. _this.tipObj.typeColor = _this.tipObj.success
  551. if (successNum > 0) {
  552. _this.startUpload = false
  553. callback(_this.result(urlArr, successNum))
  554. } else {
  555. _this.startUpload = false
  556. callback(urlArr) //错误的返回
  557. }
  558. }
  559. })
  560. }
  561. } else {
  562. _this.tipObj.prompt = '请先选择图片后上传!'
  563. _this.tipObj.typeColor = _this.tipObj.warning
  564. }
  565. } else {
  566. _this.tipObj.prompt = '在异步模式下无法调用upload方法。'
  567. _this.tipObj.typeColor = _this.tipObj.warning
  568. }
  569. },
  570. result(urlArr, successNum) {
  571. let result = {
  572. result: 'success',
  573. code: 0,
  574. urlArray: urlArr,
  575. success: successNum
  576. }
  577. return result
  578. },
  579. uploadImg(item, callback) {
  580. const _this = this
  581. console.log(_this.formData)
  582. let subUrl = _this.pressImg >= 0 ? item.pressUrl : item.url
  583. console.log('文件上传')
  584. uni.uploadFile({
  585. url: _this.url,
  586. filePath: subUrl,
  587. formData: _this.formData,
  588. header: _this.headers,
  589. name: 'file',
  590. success: (uploadFileRes) => {
  591. if (uploadFileRes) {
  592. let res = JSON.parse(uploadFileRes.data)
  593. res.resCode = 0
  594. callback(res)
  595. }
  596. },
  597. fail: (e) => {
  598. callback({
  599. resCode: 500,
  600. msg: '图片上传失败',
  601. localUrl: item,
  602. reason: e
  603. })
  604. }
  605. })
  606. },
  607. changeHeader(header) {
  608. const _this = this
  609. if (Array.isArray(header)) {
  610. for (let item of header) {
  611. for (let key in item) {
  612. _this.headers[key] = item[key]
  613. }
  614. }
  615. } else {
  616. _this.tipObj.prompt = '请使用数组格式的Header传参'
  617. _this.tipObj.typeColor = _this.tipObj.error
  618. }
  619. },
  620. //是异步方法的提交
  621. hasAysnc() {
  622. const that = this
  623. if (that.async) {
  624. let startIndex = that.imgArray.length
  625. //直接上传
  626. that.asyncUpload(startIndex)
  627. } else {
  628. that.$emit('result', {
  629. code: 500,
  630. msg: '同步模式下,我不会被调用哦~'
  631. })
  632. }
  633. },
  634. checkPlatform() {
  635. const that = this
  636. let canUse = true
  637. //#ifdef H5
  638. that.tipObj.prompt = '该环境不支持图片压缩,图片压缩功能不会生效。'
  639. that.tipObj.must = true
  640. that.tipObj.typeColor = that.tipObj.warning
  641. canUse = false
  642. that.hasAysnc()
  643. //#endif
  644. return canUse
  645. },
  646. getSysInfo() {
  647. const that = this
  648. try {
  649. const res = uni.getSystemInfoSync()
  650. that.sysInfo = {
  651. screenWidth: res.screenWidth,
  652. screenHeight: res.screenHeight
  653. }
  654. } catch (e) {
  655. // error
  656. }
  657. }
  658. }
  659. }
  660. </script>
  661. <style scoped>
  662. @font-face {
  663. font-family: 'icon_upload';
  664. /* project id 2170343 */
  665. src: url('//at.alicdn.com/t/font_2170343_nij8dm8i18.eot');
  666. src: url('//at.alicdn.com/t/font_2170343_nij8dm8i18.eot?#iefix') format('embedded-opentype'),
  667. url('//at.alicdn.com/t/font_2170343_nij8dm8i18.woff2') format('woff2'),
  668. url('//at.alicdn.com/t/font_2170343_nij8dm8i18.woff') format('woff'),
  669. url('//at.alicdn.com/t/font_2170343_nij8dm8i18.ttf') format('truetype'),
  670. url('//at.alicdn.com/t/font_2170343_nij8dm8i18.svg#iconfont') format('svg');
  671. }
  672. .icon_upload {
  673. font-family: 'icon_upload' !important;
  674. font-size: 30rpx;
  675. font-style: normal;
  676. -webkit-font-smoothing: antialiased;
  677. -webkit-text-stroke-width: 0.2px;
  678. -moz-osx-font-smoothing: grayscale;
  679. }
  680. .w-100 {
  681. width: 100%;
  682. }
  683. .flex {
  684. /* 转为弹性盒模型*/
  685. display: flex;
  686. }
  687. .flex_bet {
  688. /* 两端左右*/
  689. display: flex;
  690. justify-content: space-between;
  691. }
  692. .flex_wrap {
  693. /* 转为弹性盒模型并自动换行*/
  694. display: flex;
  695. flex-wrap: wrap;
  696. }
  697. .flex_xy_center {
  698. display: flex;
  699. justify-content: center;
  700. align-items: center;
  701. }
  702. .imgupload image {
  703. height: 100%;
  704. width: 100%;
  705. }
  706. .upload-img-view {
  707. /* height: 200rpx;
  708. width: 32%; */
  709. width: 158rpx;
  710. height: 158rpx;
  711. border-radius: 10rpx;
  712. border: 4rpx dotted #f1f1f1;
  713. /* background-color: #F1F1F1; */
  714. }
  715. .single-add {
  716. width: 100%;
  717. height: inherit;
  718. min-height: 200rpx;
  719. border-radius: 10rpx;
  720. border: 4rpx dotted #f1f1f1;
  721. }
  722. .upload-img-view>text,
  723. .single-add>text {
  724. font-size: 70rpx;
  725. color: #949494;
  726. }
  727. .upload-img-view .add,
  728. .single-add .add {
  729. font-size: 55rpx;
  730. }
  731. .upload-txt {
  732. font-size: 24rpx;
  733. color: #ffffff;
  734. }
  735. .imgs-view {
  736. /* height: 200rpx;
  737. width: 31.5%; */
  738. width: 158rpx;
  739. height: 158rpx;
  740. border-radius: 10rpx;
  741. margin-right: 1.8%;
  742. margin-bottom: 16rpx;
  743. border: 1rpx solid #f1f1f1;
  744. box-sizing: border-box;
  745. position: relative;
  746. }
  747. .single-css {
  748. width: 100%;
  749. height: inherit;
  750. min-height: 200rpx;
  751. border-radius: 10rpx;
  752. border: 1rpx solid #f1f1f1;
  753. box-sizing: border-box;
  754. position: relative;
  755. }
  756. .result {
  757. position: absolute;
  758. bottom: 0;
  759. width: 100%;
  760. height: 45rpx;
  761. font-size: 26rpx;
  762. left: 0;
  763. background-color: rgba(0, 0, 0, 0.6);
  764. text-align: center;
  765. line-height: 45rpx;
  766. border-bottom-left-radius: 10rpx;
  767. border-bottom-right-radius: 10rpx;
  768. }
  769. .result>.success {
  770. color: #00b900;
  771. }
  772. .result>.error {
  773. color: #b52e25;
  774. }
  775. .uploading {
  776. position: absolute;
  777. background-color: rgba(0, 0, 0, 0.5);
  778. left: 0;
  779. top: 0;
  780. width: 100%;
  781. height: 100%;
  782. text-align: center;
  783. line-height: 100%;
  784. z-index: 999;
  785. }
  786. .uploading image {
  787. width: 60rpx;
  788. height: 60rpx;
  789. z-index: 1000;
  790. animation: rotation 1s linear infinite;
  791. -moz-animation: rotation 1s linear infinite;
  792. -webkit-animation: rotation 1s linear infinite;
  793. -o-animation: rotation 1s linear infinite;
  794. }
  795. .uploading text {
  796. display: inline-block;
  797. font-size: 50rpx;
  798. color: #fffdef;
  799. z-index: 1000;
  800. animation: rotation 1s linear infinite;
  801. -moz-animation: rotation 1s linear infinite;
  802. -webkit-animation: rotation 1s linear infinite;
  803. -o-animation: rotation 1s linear infinite;
  804. }
  805. @keyframes rotation {
  806. from {
  807. -webkit-transform: rotate(0deg);
  808. transform: rotate(0deg);
  809. -moz-transform: rotate(0deg);
  810. -o-transform: rotate(0deg);
  811. }
  812. to {
  813. -webkit-transform: rotate(360deg);
  814. transform: rotate(360deg);
  815. -moz-transform: rotate(360deg);
  816. -o-transform: rotate(360deg);
  817. }
  818. }
  819. .imgs-view>image,
  820. .single-css>image {
  821. width: 100%;
  822. height: 100%;
  823. border-radius: 10rpx;
  824. }
  825. .imgupload__tip {
  826. font-size: 24rpx;
  827. color: #ff0000;
  828. margin: 10rpx auto;
  829. }
  830. .imgupload__tip>label {
  831. color: #009100;
  832. }
  833. .del-btn {
  834. position: absolute;
  835. top: 0;
  836. right: 0;
  837. width: 32rpx;
  838. height: 32rpx;
  839. z-index: 999;
  840. }
  841. .del-btn>image {
  842. width: 100%;
  843. height: 100%;
  844. display: flex;
  845. }
  846. .del-btn-style-2 {
  847. position: absolute;
  848. top: 0;
  849. right: 0;
  850. width: 32rpx;
  851. height: 32rpx;
  852. z-index: 999;
  853. }
  854. .del-btn-style-1 {
  855. position: absolute;
  856. top: 0;
  857. right: 0;
  858. width: 44rpx;
  859. height: 44rpx;
  860. z-index: 10;
  861. background: rgba(0, 0, 0, 0.3);
  862. color: #ececec;
  863. border-bottom-left-radius: 30rpx;
  864. display: flex;
  865. justify-content: center;
  866. align-items: center;
  867. font-size: 24rpx;
  868. }
  869. .result-style {
  870. position: absolute;
  871. bottom: 0;
  872. left: 0;
  873. right: 0;
  874. /* width: 75%; */
  875. height: 44rpx;
  876. /* border-top-right-radius: 50rpx; */
  877. display: flex;
  878. justify-content: center;
  879. align-items: center;
  880. transition: all 0.5s ease;
  881. transform: translateX(-100%);
  882. opacity: 0.4;
  883. }
  884. .result-1 {
  885. background: rgba(7, 169, 19, 0.75);
  886. color: white;
  887. transform: translateX(0%);
  888. font-size: 24rpx;
  889. opacity: 1;
  890. }
  891. .result-2 {
  892. background: rgba(239, 0, 5, 0.7);
  893. color: #dadada;
  894. font-size: 24rpx;
  895. transform: translateX(0%);
  896. opacity: 1;
  897. }
  898. </style>

使用封装的上传的组件

核心代码如下:

  1. <template>
  2. <!-- 其他页面代码 -->
  3. <!-- 图片上传组件 -->
  4. <imgUpload ref="imgUploadRef" :baseUrl="config.baseUrl" :formData="imgFormData" :imgArr="subData.ImaArray"
  5. :header="header" imgCount="9" uploadImgCount="9" :imgSize="30" :url="uploadUrl" :async="true"
  6. :previewMany="true" :pressImg="50" :beforUploadHandle="addImgBeforHandle" />>
  7. <!-- 其他页面代码 -->
  8. </template>
  9. <script setup lang="ts">
  10. import { ref, reactive } from 'vue'
  11. import { onLoad, onShow } from '@dcloudio/uni-app'
  12. import config from '@/common/config.ts'
  13. import dayjs from 'dayjs'
  14. // 引用图片上传的组件
  15. import imgUpload from '@/pages/components/imgUpload.vue'
  16. // ------------------------图片上传相关----------------------------
  17. let info = uni.getStorageSync('loginInfo')
  18. const token = info?.resData?.access_token
  19. const header = ref([{ Authorization: `Bearer ${token}` }])
  20. const addImgBeforHandle = (file: any) => {
  21. // console.log(file)
  22. return new Promise((resolve, reject) => {
  23. resolve(1)
  24. })
  25. }
  26. // 图片上传请求的后端地址(这个一般后端会统一封装的)
  27. const uploadUrl = ref(`${config.baseUrl}/oss/api/SmartFiles/UpLoadFormFile`)
  28. // 图片上传携带的参数
  29. const imgFormData = reactive({
  30. // 图片桶的名称
  31. BucketName: 'teacher-growing',
  32. /*
  33. 桶里边存放图片的文件夹,一月一个文件夹,防止单个文件夹的图片数量过多了
  34. (这个也可以在后台上传接口的时候处理,前面就可以不用管这个了,当然也可以传就相当于是一个二级文件夹)
  35. */
  36. FilePath: dayjs().format('YYYYMM'),
  37. FileType: 1
  38. })
  39. // 提交携带的参数,除了图片还有一些其他的参数根据自己实际项目需求来即可
  40. const subData = reactive<{
  41. TaskTitle: string
  42. Comment: string
  43. // 图片上传后存储的参数
  44. ImaArray: Array<any>
  45. Tag: string
  46. }>({
  47. TaskTitle: '',
  48. Comment: '',
  49. ImaArray: [],
  50. Tag: ''
  51. })
  52. </script>

欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)

评价

uniapp APP开发基础

前言uniapp是基于vue.js实现的,代码实现方法不能用jQuery的思路去解决问题,基本使用template: 模板view: 视图,使用时把v...

uniapp页面跳转传递参数过长

前言页面传递参数过长如果需要传递的参数content过长,传递的时候会有问题所以使用encodeURIComponent来传递uni.navigateTo...

uniapp webview跳转到app内部页面

官方文档:https://ask.dcloud.net.cn/article/35083相关问题:https://ask.dcloud.net.cn/question/93777引入需要的Js:&lt...

uniapp中webview跳转到app内部页面

官方文档:https://ask.dcloud.net.cn/article/35083第一步:在webview加载的页面引入Js&lt;!--uni的SDK,必须引用。--&gt;...

uniapp返回上一级页面刷新页面

当前页面: //uniapp返回上一级页面刷新页面 let pages = getCurrentPages(); // 当前页面 let beforePage ...

uniapp uni.navigateBack无法返回

注意测试的时候,不要直接打开当前页进行测试。要从其他页面点进去在返回测试。不然你获取上一页是没有的,就会报错。

uniapp确认提示框

代码如下: uni.showModal({ title: &#39;提示&#39;, content: &#39;这是一个模态弹窗&#39;, success: fun...

uni-app 微信小程序 上传图片文件uniapp。uni-file-picker 和数据一起上传图片上传图片的时候携带数据。多图上传

[TOC]uni-app中上传图片可以使用方法uni.uploadFileuni.uploadFile官方文档:https://uniapp.dcloud.net.cn/api/request/ne...

uniapp预览图片详解

一、预览图片的基本用法在uniapp中,我们可以使用uni.previewImage()API对图片进行预览,具体使用方法如下: uni.previewI...

uniapp文档在线浏览pdfexcelword等

示例代码uni.downloadFile({ url: &#39;https://example.com/somefile.pdf&#39;, success: function (res) { va...

uniapp vue3 引用样式表样式

这样即可: &lt;style scoped lang=&quot;scss&quot;&gt; @import &#39;@/static/css/report-box.scss&#39;; &lt;/style...

uniapp 离线打包配置

下载Android Studio 并配置好JavaSDK查看HBuilderX版本然后去下载对应的SDK版本https://pan.baidu.com/s/1ZYxRVH23EbldPQqO...

uniapp 离线打包配置高德地图

没有申请key的去高德开放平台申请的Android平台Keyhttps://console.amap.com/dev/key/app SHA1 在前面申请云端证书里面找 ...

uniapp 应用热更新进度条/权限

/** * 检查安装应用权限 */ checkInstallPermission() { return new Promise((resolve, reject) =&gt; { tr...

uniapp plus.runtime.install 安装失败

APP 权限配置添加&quot;&lt;uses-permission android:name=\&quot;android.permission.REQUEST_INSTALL_PACKAGES\&quot;/&g...