当前位置:   article > 正文

uniapp实现图片和视频上传_uniapp上传视频

uniapp上传视频

模板部分

  1. <template>
  2. <view class="annex-wrap ">
  3. <view class="annex-box">
  4. <view class="file-list flex-wrap">
  5. <view class="file-list-item" v-for="(item, index) in dataList" :key="index">
  6. <view class="file-list-item-inner">
  7. <!--图片-->
  8. <view class="" @tap.stop="toPreview(item)" style="position: relative;height: 100%;width: 100%;">
  9. <image :src="item.type === 'image' ? item.url : `${item.url}?x-oss-process=video/snapshot,t_0,f_jpg`" class="upload-temp-img" mode="aspectFill"
  10. />
  11. <!--视频-->
  12. <!-- <view v-if="item.type === 'video'" class="file-area">
  13. <view @tap.stop="toPreview(item)">
  14. <view class="name">{{ item.fileName }}</view>
  15. </view>
  16. </view> -->
  17. <u-icon name="play-circle-fill" color="#00000080" size="40" v-if="item.type === 'video'" style="position: absolute;top: 50%;left: 50%;transform: translate(-50%,-50%);"></u-icon>
  18. </view>
  19. <view @tap.stop="removeFile(index)" class="close-btn">
  20. <u-icon name="close" size="20"></u-icon>
  21. </view>
  22. </view>
  23. </view>
  24. <view class="file-list-item" @tap.stop="toShowChooseSheet" v-if="dataList.length<maxFilesNum">
  25. <view class="file-list-item-inner upload-btn flex-center">
  26. <view class="flex-center" style="flex-direction: column;">
  27. <u-icon name="plus" color="#929AA5" size="36"></u-icon>
  28. <view>{{ dataList.length }}/{{ maxFilesNum }}</view>
  29. </view>
  30. </view>
  31. </view>
  32. </view>
  33. </view>
  34. <u-action-sheet :actions="uploadTypeList" :show="showUploadTypeSheet" title="请选择上传文件类型"
  35. @close='showUploadTypeSheet=false' :round="20" closeOnClickOverlay cancelText='取消'
  36. @select="chooseUploadType"></u-action-sheet>
  37. <u-popup :show="showPreview" mode="center" width="95%" @close="closePreview" v-if="play" class="pop" closeOnClickOverlay>
  38. <view class="preview-content flex-center">
  39. <image :src="previewItem.url" mode="widthFix" v-if="previewItem.type === 'image'" style="width: 80%;"></image>
  40. <video :src="previewItem.url" id="preview-video" :autoplay="false" controls :show-progress="true" style=" height: 400px;width: 100vw;"
  41. :show-center-play-btn="true" v-if="previewItem.type === 'video'"></video>
  42. </view>
  43. </u-popup>
  44. </view>
  45. </template>

js部分

  1. <script>
  2. import COS from 'cos-wx-sdk-v5'
  3. import {
  4. coskey
  5. } from '@/api/common'
  6. import {
  7. qcloudTempSecreKey
  8. } from '@/api/newApi/mine'
  9. export default {
  10. props: {
  11. maxFilesNum: {
  12. type: Number,
  13. default: 1
  14. },
  15. play: {
  16. type: Boolean,
  17. default: false
  18. },
  19. videoCount:{
  20. type: Number,
  21. default: 1,
  22. }
  23. },
  24. data() {
  25. return {
  26. showPreview: false,
  27. previewItem: {
  28. url: "",
  29. type: "",
  30. },
  31. uploadTypeList: [{
  32. name: "图片",
  33. id: 1,
  34. },
  35. {
  36. name: "视频",
  37. id: 2,
  38. },
  39. ],
  40. dataList: [],
  41. showUploadTypeSheet: false,
  42. };
  43. },
  44. created() {
  45. this.getCosFun()
  46. },
  47. methods: {
  48. //获取腾讯云配置
  49. getCosFun() {
  50. const fun = () => this.isMall ? qcloudTempSecreKey() : coskey({
  51. custom: {
  52. auth: true
  53. }
  54. })
  55. fun().then(res => {
  56. this.$u.vuex('vuex_coskey', res)
  57. const {
  58. credentials,
  59. expiredTime
  60. } = res
  61. this.$u.vuex('vuex_cosapi', new COS({
  62. ForcePathStyle: true,
  63. getAuthorization: (options, callback) => {
  64. callback({
  65. TmpSecretId: credentials.tmpSecretId,
  66. TmpSecretKey: credentials.tmpSecretKey,
  67. XCosSecurityToken: credentials.sessionToken,
  68. ExpiredTime: expiredTime
  69. });
  70. }
  71. }))
  72. })
  73. },
  74. // 获取附件列表-查看或编辑时候用
  75. getFileList() {
  76. let data = {
  77. id: id,
  78. };
  79. getFileList(data).then((res) => {
  80. if (res.code === 200) {
  81. this.dataList = res.result;
  82. this.dataList.forEach((item) => {
  83. item,
  84. (item.tempFilePath = `域名/file/downloadFile?filePath=${item.filePath}`);
  85. //tempFilePath:文件的临时地址,或者拼一个获取文件临时地址的接口,临时文件地址才可以预览
  86. });
  87. }
  88. });
  89. },
  90. // 打开预览
  91. toPreview(item) {
  92. this.showPreview = true;
  93. this.previewItem = {
  94. url: item.url,
  95. type: item.type,
  96. };
  97. },
  98. // 关闭预览
  99. closePreview() {
  100. console.log(1111)
  101. this.showPreview = false
  102. this.previewItem = {
  103. url: "",
  104. fileType: "",
  105. };
  106. },
  107. // 移除文件
  108. removeFile(index) {
  109. let that = this;
  110. uni.showModal({
  111. title: "提示",
  112. content: "确定删除此项吗?",
  113. success: function(res) {
  114. if (res.confirm) {
  115. that.dataList.splice(index, 1);
  116. that.$emit('success', that.dataList)
  117. }
  118. },
  119. });
  120. },
  121. // 上传图片
  122. chooseImage() {
  123. let that = this;
  124. uni.chooseImage({
  125. count: this.maxFilesNum - this.dataList.length, //默认100
  126. sizeType: ["original", "compressed"], //可以指定是原图还是压缩图,默认二者都有
  127. sourceType: ["album", "camera"],
  128. success: ({
  129. tempFiles
  130. }) => {
  131. // 图片批量上传
  132. tempFiles.map(({
  133. path,
  134. name,
  135. type,
  136. size
  137. }) => {
  138. this.uploadFilePromise({
  139. url: path,
  140. name,
  141. type: 'image',
  142. size
  143. }).then(result => {
  144. this.dataList.push(result)
  145. this.$emit('success', this.dataList)
  146. })
  147. })
  148. },
  149. });
  150. },
  151. // 上传视频
  152. chooseVideo() {
  153. let that = this;
  154. uni.chooseVideo({
  155. sourceType: ["album", "camera"],
  156. success: ({
  157. tempFile,
  158. duration,
  159. tempFilePath,
  160. size,
  161. name
  162. }) => {
  163. console.log({
  164. tempFile,
  165. duration,
  166. tempFilePath,
  167. size,
  168. name
  169. })
  170. this.uploadFilePromise({
  171. url: tempFilePath,
  172. name,
  173. type: 'video',
  174. size
  175. }).then(result => {
  176. console.log('result', result)
  177. this.dataList.push(result)
  178. this.$emit('success', this.dataList)
  179. })
  180. },
  181. });
  182. },
  183. // 选择上传文件类型
  184. chooseUploadType({
  185. id
  186. }) {
  187. if (id === 1) {
  188. // 图片
  189. this.chooseImage();
  190. } else if (id === 2) {
  191. // 视频
  192. if(this.dataList.filter(ele=>ele.type == 'video').length < this.videoCount) this.chooseVideo()
  193. else uni.showToast({ title: `最多只能上传${this.videoCount}个视频`, icon: "none", });
  194. }
  195. },
  196. // 打开文件上传选择类型弹窗
  197. toShowChooseSheet() {
  198. if (this.dataList.length >= this.maxFilesNum) {
  199. uni.showToast({
  200. title: `最多只能上传${this.maxFilesNum}个文件`,
  201. icon: "none",
  202. });
  203. return false;
  204. } else {
  205. console.log(33333, '++++++++++', this.dataList.length, this.maxFilesNum)
  206. this.showUploadTypeSheet = true;
  207. }
  208. },
  209. uploadFilePromise({
  210. url,
  211. name,
  212. type
  213. }) {
  214. return new Promise((resolve, reject) => {
  215. if (url) {
  216. var oldStr = url.match('[^/]+(?!.*/)')[0]
  217. var newStr = this.vuex_coskey.tempUploadPath + oldStr
  218. // #ifdef H5
  219. newStr += name.slice(-4)
  220. // #endif
  221. this.vuex_cosapi.postObject({
  222. Bucket: this.vuex_coskey.bucket,
  223. Region: this.vuex_coskey.region,
  224. Key: newStr,
  225. FilePath: url
  226. }, (err, data) => {
  227. console.log('+++++++++++++++++++++++++++++++++++', newStr,data)
  228. if (data) resolve({
  229. url: `https://${data.Location}`,
  230. temp: newStr,
  231. type
  232. })
  233. else uni.showToast({
  234. icon: 'none',
  235. position: 'center',
  236. title: '上传失败,请重新上传'
  237. })
  238. })
  239. }
  240. })
  241. },
  242. },
  243. }
  244. </script>
  1. <style lang="scss" scoped>
  2. .annex-wrap {
  3. width: 100%;
  4. .err-color {
  5. color: #f00;
  6. }
  7. .border-dashed {
  8. margin: 24rpx 0;
  9. border: 1px dashed #eff0f2;
  10. }
  11. .icon-arrow {
  12. margin-left: 12rpx;
  13. }
  14. .annex-box {
  15. background: #ffffff;
  16. border-radius: 10px;
  17. // margin-top: 24rpx;
  18. color: #475569;
  19. // margin-top: 24rpx;
  20. // padding: 24rpx 34rpx;
  21. position: relative;
  22. overflow: hidden;
  23. position: relative;
  24. line-height: 1.6;
  25. .lab {
  26. font-size: 28rpx;
  27. color: #475569;
  28. padding: 10rpx;
  29. }
  30. &.select-box {
  31. padding: 0 34rpx;
  32. .u-form-item {
  33. color: #475569;
  34. padding: 16rpx 0;
  35. }
  36. }
  37. .mt-10 {
  38. margin-top: 10rpx;
  39. }
  40. .top {
  41. position: relative;
  42. .left {
  43. margin-right: 150rpx;
  44. }
  45. .title {
  46. font-size: 34rpx;
  47. color: #303133;
  48. font-weight: 550;
  49. }
  50. .desc {
  51. color: #929aa5;
  52. font-size: 24rpx;
  53. }
  54. .user-tag {
  55. margin-left: 24rpx;
  56. background-color: #f4f9ff;
  57. color: #1890ff;
  58. font-size: 22rpx;
  59. display: inline-block;
  60. border-radius: 6rpx;
  61. padding: 4rpx 20rpx;
  62. .text {
  63. margin-left: 10rpx;
  64. }
  65. }
  66. .right-icon {
  67. position: absolute;
  68. right: 0rpx;
  69. top: -20rpx;
  70. .icon {
  71. width: 170rpx;
  72. height: 170rpx;
  73. }
  74. }
  75. .result-items {
  76. overflow: hidden;
  77. .result-item {
  78. width: 33%;
  79. float: left;
  80. padding: 12rpx 0;
  81. text-align: center;
  82. position: relative;
  83. .red {
  84. color: #ff7676;
  85. }
  86. }
  87. .result-item:after {
  88. height: 60rpx;
  89. width: 1px;
  90. border-left: 1px solid #eff0f2;
  91. content: "";
  92. display: inline-block;
  93. position: absolute;
  94. right: 0;
  95. top: 50%;
  96. transform: translateY(-50%);
  97. }
  98. .result-item:nth-child(3n):after {
  99. display: none;
  100. }
  101. .name {
  102. color: #929aa5;
  103. font-size: 24rpx;
  104. }
  105. .num {
  106. color: #303133;
  107. font-size: 30rpx;
  108. }
  109. }
  110. }
  111. }
  112. .file-list-item {
  113. width: 172rpx;
  114. padding: 20rpx;
  115. height: 172rpx;
  116. margin-right: 10rpx;
  117. position: relative;
  118. display: inline-block;
  119. margin-bottom: 30rpx;
  120. overflow: hidden;
  121. &-inner {
  122. position: absolute;
  123. left: 0;
  124. right: 0;
  125. top: 0;
  126. bottom: 0;
  127. width: 100%;
  128. height: 100%;
  129. display: flex;
  130. .upload-temp-img {
  131. max-width: 100%;
  132. max-height: 100%;
  133. border-radius: 10rpx;
  134. }
  135. }
  136. .upload-btn {
  137. // border: 2px dashed #e2e8f0;
  138. border: 2rpx solid #e2e8f0;
  139. border-radius: 10rpx;
  140. background: #fff;
  141. text-align: center;
  142. font-size: 26rpx;
  143. color: #929aa5;
  144. cursor: pointer;
  145. }
  146. &:nth-child(3n) {
  147. margin-right: 0;
  148. }
  149. .file-area {
  150. position: relative;
  151. display: flex;
  152. align-items: center;
  153. justify-content: center;
  154. background: rgba(77, 151, 255, 0.05);
  155. text-align: center;
  156. width: 100%;
  157. border-radius: 10rpx;
  158. .name {
  159. white-space: nowrap;
  160. overflow: hidden;
  161. text-overflow: ellipsis;
  162. width: 160rpx;
  163. }
  164. .icon-file {
  165. width: 60rpx;
  166. height: 74rpx;
  167. }
  168. video {
  169. width: 100%;
  170. height: 100%;
  171. }
  172. }
  173. .close-btn {
  174. position: absolute;
  175. right: 0;
  176. top: 0;
  177. background: rgba(71, 85, 105, 0.3);
  178. border-radius: 0px 10rpx 0px 10rpx;
  179. display: inline-block;
  180. width: 40rpx;
  181. height: 40rpx;
  182. cursor: pointer;
  183. text-align: center;
  184. color: #fff;
  185. z-index: 9;
  186. }
  187. }
  188. .file-list-item:nth-child(3n){
  189. margin-right: 0;
  190. }
  191. .file-list-item:last-child:nth-child(3n-1){
  192. margin-right: 240rpx;
  193. }
  194. }
  195. .preview-content {
  196. width: 100vw;
  197. // height: 90vh;
  198. text-align: center;
  199. display: flex;
  200. align-items: center;
  201. video {
  202. width: 100%;
  203. height: 100%;
  204. }
  205. }
  206. /deep/ .pop {
  207. .u-popup__content {
  208. background-color: unset;
  209. }
  210. }
  211. .file-list{
  212. justify-content: space-between;
  213. }
  214. </style>

使用

  1. <template>
  2. <view class="containerbox">
  3. <my-upload :maxFilesNum='6' width="65.2" height="65.2" @success='uploadSuccess' :videoCount="3"></my-upload>
  4. </view>
  5. </template>
  6. <script>
  7. import myUpload from '@/pages/newPages/mall/music/components/my-upload.vue'
  8. import form from './form'
  9. export default {
  10. components: { myUpload },
  11. methods: {
  12. uploadSuccess(e){
  13. console.log(e)
  14. }
  15. }
  16. }
  17. </script>

效果展示

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号