选择视频 例子测试没有通过,需要根据官方文档重新写
基于 Vue3 + Vite + UI 库开发 WebApp(H5 应用)
另外调用相机拍照 和录音需要测试
html
<template>
<div class="video-upload-container" style="padding: 20px; max-width: 500px; margin: 0 auto;">
<!-- 1. 美化后的文件选择按钮 -->
<label class="custom-file-btn">
选择本地视频
<input
type="file"
accept="video/*"
@change="handleVideoSelect"
class="file-input"
/>
</label>
<!-- 2. 固定宽高的视频预览组件 -->
<div class="video-preview-wrapper" v-if="videoUrl">
<video
:src="videoUrl"
controls
class="video-player"
poster=""
>
您的浏览器不支持视频播放
</video>
</div>
<!-- 3. 无视频时的占位提示 -->
<div v-else class="video-placeholder">
请选择本地视频文件
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onUnmounted } from 'vue'
// 存储视频预览链接
const videoUrl = ref<string>('')
/**
* 处理视频选择逻辑
*/
const handleVideoSelect = (e: Event) => {
const target = e.target as HTMLInputElement
const file = target.files?.[0]
if (!file) {
videoUrl.value = ''
return
}
// 校验视频类型
if (!file.type.startsWith('video/')) {
alert('请选择有效的视频文件!')
target.value = ''
return
}
try {
videoUrl.value = URL.createObjectURL(file)
} catch (error) {
console.error('视频预览失败:', error)
alert('视频预览出错,请重试!')
}
}
// 组件卸载时释放临时 URL
onUnmounted(() => {
if (videoUrl.value) {
URL.revokeObjectURL(videoUrl.value)
}
})
</script>
<style scoped>
/* 美化文件选择按钮 */
.custom-file-btn {
display: inline-block;
padding: 12px 24px;
background-color: #409eff;
color: white;
border-radius: 8px;
cursor: pointer;
font-size: 15px;
transition: background-color 0.3s;
margin-bottom: 20px;
}
.custom-file-btn:hover {
background-color: #66b1ff;
}
/* 隐藏原生文件选择框 */
.file-input {
display: none;
}
/* 视频容器:固定宽高(示例:400x225,16:9比例) */
.video-preview-wrapper {
width: 400px;
height: 225px;
border-radius: 8px;
overflow: hidden;
border: 1px solid #eee;
}
/* 视频组件:填满容器,固定宽高 */
.video-player {
width: 100%;
height: 100%;
object-fit: cover; /* 保持视频比例,填满容器(可选:contain 显示完整视频) */
}
/* 无视频时的占位样式 */
.video-placeholder {
width: 400px;
height: 225px;
line-height: 225px;
text-align: center;
color: #999;
border: 1px dashed #eee;
border-radius: 8px;
background-color: #f9f9f9;
}
/* 移动端适配:小屏幕下缩小固定宽高 */
@media (max-width: 420px) {
.video-preview-wrapper,
.video-placeholder {
width: 300px;
height: 169px; /* 保持16:9比例 */
}
}
</style>
在 Vue3 项目中,若你遇到「调用系统图库选择图片 / 音频时,却只显示视频」的问题,核心原因并非 Vue3 本身的问题,而是:
- 原生
<input type="file">的accept属性在不同系统 / 浏览器下的解析差异; - 移动端系统图库对文件类型的分类逻辑(比如部分安卓机型会把 Live Photo、动图等识别为视频);
- 缺少对文件选择行为的精细化控制(仅靠原生 input 无法强制过滤系统图库的展示内容)。
针对这个问题,Vue3 生态中有专门的文件选择 / 媒体选择库可以解决,以下是最实用的方案:
一、核心解决方案:使用成熟的移动端文件选择库
这些库封装了原生文件选择的兼容逻辑,能精准控制图库展示的文件类型,解决「只显示视频」的问题。
表格
| 库名称 | 核心优势 | 安装命令 | 官网 / 文档地址 |
|---|---|---|---|
| Vant Uploader | 基于 Vant 生态,适配移动端,支持精准指定文件类型,和你之前用的 Vant 兼容 | npm i vant |
https://vant-contrib.gitee.io/vant/#/zh-CN/uploader |
| vue3-filepond | 功能强大,支持文件类型过滤、预览、裁剪,适配移动端 | npm i filepond vue3-filepond |
https://pqina.nl/filepond/docs/patterns/frameworks/vue/ |
| tdesign-mobile-vue | 腾讯出品的移动端组件库,Upload 组件支持精准控制文件类型 | npm i tdesign-mobile-vue |
https://tdesign.tencent.com/mobile-vue/components/upload |
二、最推荐:Vant Uploader(和你现有代码兼容)
Vant 是你之前优先选择的 Vue3 移动端库,其 Uploader 组件能精准控制图库展示的文件类型,解决「只显示视频」的问题,且无需额外安装新依赖。
1. 图片选择(强制只显示图片,屏蔽视频)
vue
<template>
<!-- Vant Uploader 图片选择:强制只显示图片 -->
<van-uploader
v-model="fileList"
accept="image/*"
:before-read="beforeReadImage"
capture="album" <!-- 强制打开相册(而非相机) -->
multiple="false"
title="选择图片"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { VanUploader } from 'vant'
import 'vant/lib/uploader/style'
const fileList = ref([])
// 前置校验:确保只选图片(兜底过滤)
const beforeReadImage = (file: File) => {
if (!file.type.startsWith('image/')) {
alert('请选择图片文件!')
return false // 阻止上传
}
return true
}
</script>
2. 音频选择(强制只显示音频,屏蔽视频 / 图片)
vue
<template>
<van-uploader
v-model="audioFileList"
accept="audio/*"
:before-read="beforeReadAudio"
capture="album"
multiple="false"
title="选择音频"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { VanUploader } from 'vant'
import 'vant/lib/uploader/style'
const audioFileList = ref([])
const beforeReadAudio = (file: File) => {
if (!file.type.startsWith('audio/')) {
alert('请选择音频文件!')
return false
}
return true
}
</script>
3. 视频选择(仅显示视频)
vue
<template>
<van-uploader
v-model="videoFileList"
accept="video/*"
:before-read="beforeReadVideo"
capture="album"
multiple="false"
title="选择视频"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { VanUploader } from 'vant'
import 'vant/lib/uploader/style'
const videoFileList = ref([])
const beforeReadVideo = (file: File) => {
if (!file.type.startsWith('video/')) {
alert('请选择视频文件!')
return false
}
return true
}
</script>
三、关键配置说明(解决「只显示视频」的核心)
accept属性精准取值 :- 图片:
accept="image/jpeg,image/png,image/gif"(比image/*更精准,避免系统误判); - 音频:
accept="audio/mpeg,audio/wav,audio/flac"; - 视频:
accept="video/mp4,video/avi,video/mov"。
- 图片:
capture="album":强制打开系统相册(而非相机),部分机型默认打开相机 + 视频模式,加这个属性可固定打开相册。before-read前置校验:即使系统图库过滤失效,也能在代码层兜底过滤,确保只选目标类型文件。
四、为什么原生 input 会出现「只显示视频」?
- 系统兼容问题 :安卓部分机型(如小米、华为)对
accept="image/*"的解析不严格,会把 Live Photo、GIF 动图等识别为视频; - 浏览器差异 :移动端 Safari/Chrome 对
accept属性的支持度不同,部分浏览器会忽略类型过滤; - 图库分类逻辑:iOS / 安卓的系统图库会按「媒体类型」分类,若默认选中「视频」分类,就会只显示视频(原生 input 无法控制图库的默认分类)。
总结
- 解决「图库只显示视频」的核心:放弃原生 input,使用 Vant Uploader 等移动端专用库,其封装了兼容逻辑,能精准控制文件类型;
- 关键配置:
accept精准指定文件格式 +capture="album"强制打开相册 +before-read前置校验; - 最优选择:优先用 Vant Uploader(和你现有 Vue3 移动端项目兼容,无需额外安装依赖)。
如果需要把图片、视频、音频选择整合为一个组件(带标签切换),可以告诉我,我会帮你基于 Vant Uploader 实现完整版本~