@tanzhenxing/zx-upload
Version:
`zx-upload` 是一个功能强大的文件上传组件,可用于图片、视频及文件的选择、预览和上传。支持单选/多选、文件大小限制、自定义样式等功能。
407 lines (335 loc) • 8.53 kB
Markdown
# ZX-Upload 快速上手指南
## 安装使用
### 1. 复制组件文件
将 `zx-upload` 组件文件夹复制到你的 `components` 目录下:
```
components/
├── zx-upload/
│ ├── zx-upload.vue
│ ├── README.md
│ └── demo.vue
```
### 2. 注册组件
#### 全局注册 (main.js)
```javascript
import { createApp } from 'vue'
import App from './App.vue'
import ZxUpload from '@/components/zx-upload/zx-upload.vue'
const app = createApp(App)
app.component('ZxUpload', ZxUpload)
app.mount('#app')
```
#### 局部注册
```vue
<script setup>
import ZxUpload from '@/components/zx-upload/zx-upload.vue'
</script>
```
## 基础示例
### 图片上传
```vue
<template>
<view class="container">
<text class="title">选择图片</text>
<zx-upload
v-model:fileList="imageList"
accept="image"
:maxCount="9"
:multiple="true"
uploadText="添加图片"
@change="onImageChange"
/>
</view>
</template>
<script setup>
import { ref } from 'vue'
const imageList = ref([])
const onImageChange = (data) => {
console.log('图片列表:', data.fileList)
}
</script>
```
### 上传到服务器
```vue
<template>
<zx-upload
v-model:fileList="fileList"
accept="image"
:autoUpload="true"
action="https://your-server.com/api/upload"
:headers="{ Authorization: `Bearer ${token}` }"
@success="onUploadSuccess"
@error="onUploadError"
/>
</template>
<script setup>
import { ref } from 'vue'
const fileList = ref([])
const token = ref('your-auth-token')
const onUploadSuccess = (data) => {
console.log('上传成功:', data)
uni.showToast({
title: '上传成功',
icon: 'success'
})
}
const onUploadError = (data) => {
console.error('上传失败:', data)
uni.showToast({
title: '上传失败',
icon: 'error'
})
}
</script>
```
## 常用配置
### 限制文件大小和类型
```vue
<zx-upload
v-model:fileList="fileList"
accept="image"
:maxSize="2 * 1024 * 1024"
:extensions="['jpg', 'png', 'gif']"
tips="支持 JPG、PNG、GIF 格式,大小不超过 2MB"
/>
```
### 自定义样式
```vue
<zx-upload
v-model:fileList="fileList"
:size="100"
uploadIcon="camera"
uploadIconColor="#409EFF"
uploadText="拍照"
:customStyle="{ marginBottom: '20rpx' }"
/>
```
### 文件列表模式
```vue
<zx-upload
v-model:fileList="fileList"
accept="file"
listType="text"
uploadText="选择文件"
/>
```
## 服务器端配置
### Node.js (Express + Multer)
```javascript
const express = require('express')
const multer = require('multer')
const path = require('path')
const app = express()
// 配置文件存储
const storage = multer.diskStorage({
destination: 'uploads/',
filename: (req, file, cb) => {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9)
cb(null, file.fieldname + '-' + uniqueSuffix + path.extname(file.originalname))
}
})
const upload = multer({
storage,
limits: { fileSize: 10 * 1024 * 1024 }, // 10MB
fileFilter: (req, file, cb) => {
const allowedTypes = /jpeg|jpg|png|gif/
const extname = allowedTypes.test(path.extname(file.originalname).toLowerCase())
const mimetype = allowedTypes.test(file.mimetype)
if (mimetype && extname) {
return cb(null, true)
} else {
cb(new Error('只支持图片文件'))
}
}
})
// 上传接口
app.post('/api/upload', upload.single('file'), (req, res) => {
if (!req.file) {
return res.status(400).json({ error: '没有文件上传' })
}
res.json({
success: true,
url: `/uploads/${req.file.filename}`,
filename: req.file.filename,
size: req.file.size
})
})
// 错误处理
app.use((error, req, res, next) => {
if (error instanceof multer.MulterError) {
if (error.code === 'LIMIT_FILE_SIZE') {
return res.status(400).json({ error: '文件过大' })
}
}
res.status(500).json({ error: error.message })
})
app.listen(3000)
```
### PHP 后端示例
```php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: Content-Type');
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['error' => '方法不允许']);
exit;
}
if (!isset($_FILES['file'])) {
http_response_code(400);
echo json_encode(['error' => '没有文件上传']);
exit;
}
$file = $_FILES['file'];
$uploadDir = 'uploads/';
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
$maxSize = 10 * 1024 * 1024; // 10MB
// 验证文件类型
if (!in_array($file['type'], $allowedTypes)) {
http_response_code(400);
echo json_encode(['error' => '不支持的文件类型']);
exit;
}
// 验证文件大小
if ($file['size'] > $maxSize) {
http_response_code(400);
echo json_encode(['error' => '文件过大']);
exit;
}
// 生成唯一文件名
$extension = pathinfo($file['name'], PATHINFO_EXTENSION);
$filename = uniqid() . '.' . $extension;
$filepath = $uploadDir . $filename;
// 确保上传目录存在
if (!file_exists($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
// 移动文件
if (move_uploaded_file($file['tmp_name'], $filepath)) {
echo json_encode([
'success' => true,
'url' => $filepath,
'filename' => $filename,
'size' => $file['size']
]);
} else {
http_response_code(500);
echo json_encode(['error' => '文件上传失败']);
}
```
## 小程序配置
### 微信小程序
在 `manifest.json` 中配置域名白名单:
```json
{
"mp-weixin": {
"permission": {
"scope.writePhotosAlbum": {
"desc": "保存图片到相册"
}
},
"requiredBackgroundModes": ["audio"],
"usingComponents": true
}
}
```
在微信小程序管理后台配置服务器域名:
- 开发 → 开发管理 → 开发设置 → 服务器域名
- 添加 `uploadFile` 合法域名
### uni-app manifest.json 配置
```json
{
"name": "your-app",
"appid": "your-appid",
"mp-weixin": {
"appid": "wx-appid",
"setting": {
"urlCheck": false
}
},
"h5": {
"router": {
"mode": "hash"
}
}
}
```
## 常见问题
### 1. 图片不显示
- 检查图片路径是否正确
- 检查服务器是否支持跨域
- H5 端检查图片域名是否在白名单中
### 2. 上传失败
- 检查服务器接口是否正常
- 检查文件大小是否超限
- 检查网络连接状态
### 3. 小程序无法选择文件
- 检查是否配置了域名白名单
- 检查 `accept` 参数是否正确
- 部分功能仅微信小程序支持
### 4. 样式问题
- 检查是否正确引入样式文件
- 检查 rpx 单位是否正确转换
- 自定义样式可能被其他样式覆盖
## 进阶使用
### 自定义预览
```vue
<template>
<zx-upload
v-model:fileList="fileList"
@preview="onPreview"
/>
</template>
<script setup>
const onPreview = ({ file, index }) => {
// 自定义预览逻辑
if (file.type === 'video') {
// 使用自定义视频播放器
showVideoPlayer(file.url)
} else {
// 使用自定义图片预览
showImageViewer(file.url)
}
}
</script>
```
### 批量上传
```vue
<template>
<view>
<zx-upload
v-model:fileList="fileList"
:autoUpload="false"
@change="onChange"
/>
<button @tap="uploadAll">批量上传</button>
</view>
</template>
<script setup>
const uploadAll = async () => {
const readyFiles = fileList.value.filter(file => file.status === 'ready')
for (const file of readyFiles) {
try {
await uploadSingleFile(file)
} catch (error) {
console.error('上传失败:', error)
}
}
}
const uploadSingleFile = (file) => {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: 'https://your-server.com/upload',
filePath: file.url,
name: 'file',
success: resolve,
fail: reject
})
})
}
</script>
```
这样就可以快速上手使用 ZX-Upload 组件了!更多详细配置请参考 [README.md](./README.md)。