【uniapp】---- 使用 uniapp 实现视频和图片上传且都可以预览展示

发布于:2025-07-30 ⋅ 阅读:(22) ⋅ 点赞:(0)

1. 前言

接手得 uniapp 开发的微信小程序项目,新的开发需求是需要同时上传图片和视频,但是之前的上传都没有进行封装,都是每个页面需要的时候单独实现,现在新的需求,有多个地方都需要上传图片、视频或语音等,这样就需要封装一个组件,然后发现部分地方使用了 uni-file-picker 组件,但是 uni-file-picker 在 grid 的时候只能进行图片的展示,如果是 video 或者 all 的时候,就会直接列表展示的文件名列表,不满足我当前的需求,因此在 uni-file-picker 基础上进行再次适配当前需求的封装。

2. 实现效果

输入图片说明

3. 分析

  1. 图片和视频同时预览展示,就需要判断上传的是否是视频或者图片;
  2. 根据接口判断是否上传文件的格式是否在允许范围内;
  3. 使用 uni-file-picker 需要改造,将文件预览列表隐藏,使用自定义的预览文件。

4. 判断是图片

export const isImageFile = (filename) => {
	// 定义常见的图片文件扩展名
	const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg']
	// 获取文件扩展名
	const fileExtension = filename.split('.').pop().toLowerCase()
	// 判断文件扩展名是否在图片扩展名列表中
	return imageExtensions.includes(fileExtension)
}

5. 判断是视频

// 判断是不是视频
export const isVideoFile = (filename) => {
	// 定义常见的视频文件扩展名
	const videoExtensions = [
		'mp4',
		'avi',
		'mov',
		'mkv',
		'flv',
		'wmv',
		'webm',
		'mpeg',
		'mpg'
	]
	// 获取文件扩展名
	const fileExtension = filename.split('.').pop().toLowerCase()
	// 判断文件扩展名是否在视频扩展名列表中
	return videoExtensions.includes(fileExtension)
}

6. 根据接口判断是否是可上传格式文件

export const canUploadFile = (filename) => {
	const extensions = ['bmp','gif','jpg','jpe','png','mp4','mp3']
	// 获取文件扩展名
	const fileExtension = filename.split('.').pop().toLowerCase()
	// 判断文件扩展名是否在视频扩展名列表中
	return extensions.includes(fileExtension)
}

7. 预览图片和视频

uploadPreview 插槽是方便自定义预览,这里我是用 tailwindcss 实现了一个默认的视频和图片的预览样式。

<slot name="uploadPreview">
  <view class="cc mr-[20rpx] wh-[160] bd-[8] flex-none relative" v-for="(item,index) in fileLists" :key="item.url">
    <view class="icon-del-box" @click.stop="deletePic(item)">
      <view class="icon-del"></view>
      <view class="icon-del rotate"></view>
    </view>
    <image v-if="item.isImage" :src="item.url" class="wh-[160] bd-[8] flex-none"></image>
    <video v-else-if="item.isVideo" :src="item.url" class="wh-[160] bd-[8] flex-none"></video>
  </view>
</slot>

8. 使用 uni-file-picker 上传

  1. 注意:是对 list 模式的文件上传,所以直接将 mode 的值写死 list;
  2. uploadButtom 自定义上传样式。
<uni-file-picker
  :limit="limit"
  :file-mediatype="fileMediatype"
  @select="getUpload"
  :is-upload-file="false"
  :autoUpload="false"
  mode="list"
  :value="fileLists"
>
  <slot name="uploadButtom">
    <view
      class="cc bg-[#F9F9F9] wh-[160] bd-[8] b-[2rpx_#D0D0D0_dashed] flex-none"
    >
      <image :src="$icon.publishAddIcon" class="wh-[48]"></image>
    </view>
  </slot>
</uni-file-picker>

9. 完整组件实现

<template>
	<view class="ac">
		<slot name="uploadPreview">
			<view class="cc mr-[20rpx] wh-[160] bd-[8] flex-none relative" v-for="(item,index) in fileLists" :key="item.url">
				<view class="icon-del-box" @click.stop="deletePic(item)">
					<view class="icon-del"></view>
					<view class="icon-del rotate"></view>
				</view>
				<image v-if="item.isImage" :src="item.url" class="wh-[160] bd-[8

网站公告

今日签到

点亮在社区的每一天
去签到