記事ディレクトリ
序文
vant2 アップロード コンポーネント ポータル
使用vant2组件中的uploader组件
<van-uploader v-model="fileList" multiple capture :after-read="afterRead" @delete="onDelete" />
提示:以下是本篇文章正文内容,下面案例可供参考
1.base64をBlobオブジェクトに変換する方法
utils フォルダーの下に、という名前のツール js を作成します。base64toFile.js
// 转换为 Blob 对象的方法 (可复用)
export function base64ToBlob(base64Data) {
const parts = base64Data.split(";base64,");
const contentType = parts[0].split(":")[1];
const raw = window.atob(parts[1]);
const rawLength = raw.length;
const uInt8Array = new Uint8Array(rawLength);
for (let i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], {
type: contentType });
}
// 从 base64 数据中获取文件名和 mime 类型的方法 (可复用)
export function getFilenameAndMimetypeFromBase64(base64Data) {
const fileInfo = base64Data.split(';base64,')[0].substring(5).split(':');
const mimeType = fileInfo[0];
const filename = fileInfo[1];
return [filename, mimeType];
}
/**
* 用法
// 将 base64 编码的文件数据转为 Blob 对象
const blob = base64ToBlob(res);
// 获取文件名和 mime 类型
const [filename, mimeType] = getFilenameAndMimetypeFromBase64(res);
// 将 Blob 对象转换为 File 对象
const file = new File([blob], filename, { type: mimeType });
// 上传文件
const formData = new FormData();
formData.append('file', file);
axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(response => {
console.log(response.data);
}).catch(error => {
console.log(error);
});
*/
使用方法は上記コード内であり、次のような処理になります。
2. ステップを使用する
1.ツールjsの導入
コードは次のとおりです(例)。
import {
base64ToBlob,
getFilenameAndMimetypeFromBase64
} from "@/utils/base64toFile.js"
2.フォームデータアップロードメソッドの作成
アップロードをsrc /apiのフォルダーに書き込みます
コードは次のとおりです(例)。
import request from '@/utils/request'
// 上传图片
export function uploadImg(data) {
return request({
url: '/flow/common/upload',
method: 'post',
headers: {
'Content-Type': 'multipart/form-data'
},
data: data
})
}
実際の状況に応じて URL アドレスを変更し、
3. APIメソッド内のリクエストコード
utilsフォルダーに新しいものを作成しますrequest.js
import axios from 'axios'
import errorCode from '@/utils/errorCode'
import {
getToken
} from '@/utils/auth'
import {
Dialog,
Notify
} from 'vant';
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分
// baseURL: '/',
baseURL: process.env.VUE_APP_BASE_API,
// 超时
timeout: 40000
})
// request拦截器
service.interceptors.request.use(config => {
// 是否需要设置 token
const isToken = (config.headers || {
}).isToken === false
// config.headers['Authorization'] = sessionStorage.getItem('token') // 让每个请求携带自定义token 请根据实际情况自行修改
// config.headers['token'] = sessionStorage.getItem('token') // 让每个请求携带自定义token 请根据实际情况自行修改
config.headers['Authorization'] = 'Bearer ' + getToken()
// get请求映射params参数
if (config.method === 'get' && config.params) {
let url = config.url + '?';
for (const propName of Object.keys(config.params)) {
const value = config.params[propName];
var part = encodeURIComponent(propName) + "=";
if (value !== null && typeof (value) !== "undefined") {
if (typeof value === 'object') {
for (const key of Object.keys(value)) {
let params = propName + '[' + key + ']';
var subPart = encodeURIComponent(params) + "=";
url += subPart + encodeURIComponent(value[key]) + "&";
}
} else {
url += part + encodeURIComponent(value) + "&";
}
}
}
url = url.slice(0, -1);
config.params = {
};
config.url = url;
}
return config
}, error => {
console.log(error)
Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use(res => {
// 未设置状态码则默认成功状态
const code = res.data.code || 200;
// 获取错误信息
const msg = errorCode[code] || res.data.msg || errorCode['default']
// 二进制数据则直接返回
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
return res.data
}
if (code === 401) {
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
} else if (code === 402) {
Dialog.alert({
message: res.data.msg,
confirmButtonColor: "#3478F3",
}).then(() => {
});
return Promise.reject(new Error(msg))
} else if (code === 403) {
return Promise.reject(new Error(msg))
} else if (code === 500) {
Notify({
type: 'danger',
message: msg
});
return Promise.reject(new Error(msg))
} else if (code === 601) {
Notify({
type: 'warning',
message: msg
});
return Promise.reject('error')
} else if (code !== 200) {
Dialog({
title: '错误',
message: msg
});
return Promise.reject('error')
} else {
return res.data
}
},
error => {
console.log('err' + error)
let {
message
} = error;
if (message == "Network Error") {
message = "后端接口连接异常";
} else if (message.includes("timeout")) {
message = "系统接口请求超时";
} else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.substr(message.length - 3) + "异常";
}
Notify({
message: message,
type: 'danger',
duration: 5 * 1000,
});
return Promise.reject(error)
}
)
export default service
request.js には多くのツール クラスが導入されていますが、一般的な vue プロジェクトにはスキャフォールディングが必要です。スキャフォールディングがない場合、またはこの request.js をまだ見ていない場合は、Ruoyi バックグラウンド管理システムのソース コードを確認できます。これはほんの一例です。リクエスト メソッドのカプセル化に次のコードがあることを伝えます。
3. 実際の動作
1. HTMLコード
<van-uploader v-model="fileList" multiple capture :after-read="afterRead" @delete="onDelete" />
2.jsコード
インポート方法
import {
base64ToBlob,
getFilenameAndMimetypeFromBase64
} from "@/utils/base64.js"
import {
uploadImg, // 上传拍照的图片
} from "@/api/upload.js"
データ変数
fileList: [],
メソッドメソッド
afterRead(res) {
// 此时可以自行将文件上传至服务器
console.log(res, "file");
// base64格式赋值, data:image/jpeg;base64,/9j.......
const data = res.content
// 将 base64 编码的文件数据转为 Blob 对象
const blob = base64ToBlob(data);
// 获取文件名和 mime 类型
const [filename, mimeType] = getFilenameAndMimetypeFromBase64(data);
// 将 Blob 对象转换为 File 对象
const file = new File([blob], res.file.name, {
type: mimeType });
// 写入formData
const formData = new FormData();
formData.append('file', file);
// 执行上传方法
uploadImg(formData).then(res => {
console.log(res, "上传结果", this.fileList);
this.form.files.push(res.data) // 写入form参数
})
},
afterRead は vant コンポーネント アップロード モジュールのコールバックです
コールバックパラメータの内容はbase64イメージですdata:image/jpeg;base64,/9j.......
このコードのファイル名は入手できない可能性がありますが、結局のところ、これは Base64 イメージ ファイルなので、ファイル名は自分で定義できます。
// 获取文件名和 mime 类型
const [filename, mimeType] = getFilenameAndMimetypeFromBase64(res);
// 将 Blob 对象转换为 File 对象
const file = new File([blob], filename, {
type: mimeType });
要約する
Base64形式のファイルに加えて、formDataを使用してアップロードすることができ、docやpdfなどの他のドキュメントも利用できます。
只要选择文件上传,拿到的回调参数里面,有一个是file类型的,那就是这个。
これを取るファイルこれを formData に追加し、同じ方法でアップロードします。
次のように
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
<el-upload class="upload-demo" :file-list="uploadFileList" drag
:on-change="getFiles"
:on-remove="getFiles"
action="" :auto-upload="false" multiple>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFileForm">确 定</el-button>
<el-button @click="upload.open = false">取 消</el-button>
</div>
</el-dialog>
// 提交上传文件
submitFileForm() {
let formData = new FormData();
this.files.forEach(f => formData.append("files", f.raw))
fileUpload(formData).then(res => {
this.$modal.msgSuccess("上传成功")
})
this.upload.open = false;
},
getFiles(file, fileList) {
this.files = fileList;
},