Quasar Framework (Vue) Uploader 使用 apollo-upload (GraphQL)
Posted
技术标签:
【中文标题】Quasar Framework (Vue) Uploader 使用 apollo-upload (GraphQL)【英文标题】:Quasar Framework (Vue) Uploader using apollo-upload (GraphQL) 【发布时间】:2019-02-15 02:15:10 【问题描述】:我正在尝试通过 apollo-upload 使用 Quasar 的 Uploader 上传图片。
<q-uploader multiple :url="url" :upload-factory="uploadFactory"/> This is
how I implement the Uploader.
这里是uploadFactory-Function:
uploadFactory (file, updateProgress)
return(
this.$apollo.mutate(
mutation: gql`
mutation($file: Upload!)
uploadFile(file: $file)
filename
`,
variables: file: file
)
)
return new Promise(resolve, reject);
,
在服务器端我得到了这个:
async uploadFile (parent, file )
const stream, filename, mimetype, encoding = await file;
var fs = require('fs');
const id = 1;
const uploadDir = __dirname;
const path = `$uploadDir/$filename`
var wstream = fs.createWriteStream(path);
wstream.write(stream);
wstream.end();
return stream, filename, mimetype, encoding ;
,
,
到目前为止,代码。 如果我输入一个新图像并按下上传按钮,则uploadFactory 在file.__img 中有img-src。如果将数据发送到服务器,则 __img-Object 完全为空:。我尝试发送文件,只是文件.__img,尝试复制值,但每次都是空的。
有人做到了吗?还是有可能?
仅供参考:一些链接,如果您还没有听说过类星体或阿波罗: Quasar Uploader, Apollo Upload
【问题讨论】:
自从你问这个之后有什么更新吗? 【参考方案1】:我做了一个解决方法,但它可以满足我的需求。
客户:
<input-camera v-if="status=='S' && damage != null" ref="inputCamera" @photo="addFile" @popup="openPopup" @removePhoto="removeFile" v-bind:allowMultiple="true" v-bind:labelText="'Photos'" v-bind:id="id"/>
以上是我加载模块的方式。您需要处理包含模块的@photo 和@removePhoto。
这是我写的模块:
<template>
<q-uploader v-bind:value="value" ref="uploader" inverted color="red-8" :float-
label="labelText" :multiple='allowMultiple' :url="url" hide-upload-progress send-
raw hide-upload-button class="col-3" @add="addFile" @remove:cancel="removeFile"/>
</template>
<script>
import format from 'quasar'
export default
name: "input-camera",
inheritAttrs: false,
data()
return
url: '',
listenerIndex: null,
,
props: value: Boolean, allowMultiple: Boolean, labelText: String, id: String ,
methods:
addFile(file)
var resizedFile = null;
file = file[0];
var that = this;
if(file.type.match(/image.*/))
// Load the image
var metaData = ;
var reader = new FileReader();
reader.onload = function (readerEvent)
var image = new Image();
image.onload = function (imageEvent)
// Resize the image
var canvas = document.createElement('canvas'),
max_size = 1024, // edit it, or get it from another param!
width = image.width,
height = image.height;
if (width > height)
if (width > max_size)
height *= max_size / width;
width = max_size;
else
if (height > max_size)
width *= max_size / height;
height = max_size;
canvas.width = width;
canvas.height = height;
canvas.getContext('2d').drawImage(image, 0, 0, width, height);
var dataUrl = canvas.toDataURL('image/jpeg');
var type = 'image/jpeg';
//choose one of the above
resizedFile = dataUrl;
var nextId = that.$refs.uploader._data.files.length;
nextId = nextId - 1;
//add image metadata
metaData['lastModified'] = that.$refs.uploader._data.files[nextId].lastModified;
metaData['name'] = that.$refs.uploader._data.files[nextId].name;
metaData['size'] = that.$refs.uploader._data.files[nextId].size;
metaData['type'] = type;
//back to parent
that.addNextListener();
that.$emit('photo', resizedFile, that.id, metaData);
image.src = readerEvent.target.result;
reader.readAsDataURL(file);
,
removeFile(file)
var that = this;
var toFind = file.name;
var found = false;
var tempL = null;
for(let l = 0; l < this.$refs.uploader._data.files.length; l++)
if(this.$refs.uploader._data.files[l].name == toFind)
found = true;
tempL = l;
break;
if(found)
if(tempL != null) that.removeNextListener(tempL);
this.$emit('removePhoto', toFind, this.id);
,
updateUploaderImages: function(id, index, image)
// ToDo: below would work, but then we need other way to handle the original image
// this.$refs.uploader._data.files[index]['__img'].src = image;
,
addNextListener(nextListener)
var that = this;
if(nextListener == null)
nextListener = this.$refs.uploader._data.files.length-1;
const childs = this.$refs.uploader.$el.children[1].children[0].children[nextListener].children[0];
childs.id = 'image'+nextListener;
var selector = 'div#image'+nextListener;
this.listenerIndex = nextListener;
this.setListener(selector, 'click', that.openPopup, that.$refs.uploader.files[nextListener]);
else
for(let l = 0; l < nextListener.length; l++)
var listenerIndex = nextListener[l];
const childs = this.$refs.uploader.$el.children[1].children[0].children[listenerIndex].children[0];
childs.id = 'image'+listenerIndex;
var selector = 'div#image'+listenerIndex;
this.listenerIndex = listenerIndex;
this.setListener(selector, 'click', that.openPopup, that.$refs.uploader.files[listenerIndex]);
,
removeNextListener(index)
var that = this;
var nextListener = index;
var selector = 'div#image'+nextListener;
this.removeListener(selector, 'click', that.openPopup, that.$refs.uploader.files[nextListener]);
,
openPopup(img)
var that = this;
img = img['__img'].src;
this.$emit('popup', img , that.listenerIndex, that.id);
,
setListener(selector, event, callback, props)
var that = this;
var listenerElements = document.querySelectorAll(selector);
if(listenerElements != null)
for(var le=0; le<listenerElements.length; le++)
listenerElements[le].addEventListener(event, function(evt)
if(callback != null) callback(props);
);
,
removeListener(selector, event, callback, props)
var that = this;
var listenerElements = document.querySelectorAll(selector);
if(listenerElements != null)
for(var le=0; le<listenerElements.length; le++)
listenerElements[le].removeEventListener(event, function(evt)
if(callback != null) callback(props);
);
,
setImage(photos, id)
var that = this;
var index = id - 1;
var listenerIndexes = [];
for(let l = 0; l < photos.length; l++)
var length = that.$refs.uploader._data.files.length;
var img = new Image;
// img.src = photos[l][id];
img.src = photos[l][l+1];
var metadata = photos[l].metaData;
var imgObject = ;
imgObject.lastModified = metadata.lastModified;
var DateTime = new Date(metadata.lastModified);
imgObject.lastModifiedDate = DateTime;
imgObject.name = metadata.name;
imgObject.size = metadata.size;
imgObject.type = metadata.type;
imgObject.webkitRelativePath = "";
imgObject.__doneUploading = false;
imgObject.__failed = false;
imgObject.__img = img;
imgObject.__progress = 0;
imgObject.__size = (metadata.size / 1024)+" kB";
imgObject.__timestamp = metadata.lastModified;
imgObject.__uploaded = false;
this.$refs.uploader._data.files[length] = imgObject;
this.$refs.uploader.totalSize = this.$refs.uploader.totalSize +
imgObject.size;
this.$refs.uploader.queue.push(imgObject);
this.$refs.uploader.expanded = true;
listenerIndexes.push(length);
setTimeout(function()
that.addNextListener(listenerIndexes);
,50);
,
,
computed:
inputListeners: function ()
var vm = this
// `Object.assign` merges objects together to form a new object
return Object.assign(,
// We add all the listeners from the parent
this.$listeners,
// Then we can add custom listeners or override the
// behavior of some listeners.
// This ensures that the component works with v-model
input: function (event)
vm.$emit('input', event);
//if(!isNaN(event)) vm.$emit('input', event.toString().replace('.',''))
//else return event.slice(0, -1);
)
,
</script>
它还包括缩小图像并为图像设置 Clicklisteners,因此您可以在弹出窗口中打开它。如果您从服务器取回图像,您可以通过 datauri 将图像插入回上传器。
然后我只需将 imageData 添加到 json-object 并将其发送到服务器,在那里进行处理。
希望对你有所帮助。
PS:我禁用了上传按钮,因此每次添加时都会返回 photoData,然后我将其推送到数组中并开始在 UI 中的另一个按钮上发送数据。
【讨论】:
以上是关于Quasar Framework (Vue) Uploader 使用 apollo-upload (GraphQL)的主要内容,如果未能解决你的问题,请参考以下文章
“el.closest 不是 getScrollTarget 的函数”,使用 Quasar Framework (Vue)
在 Firebase + Vue + Quasar Framework 中更改个人资料图片
如何使用 Vue3 和 Typescript 在 Quasar Framework 中定义 ref 方法的类型
使用 Quasar-Framework 0.15 的 Jest 单元测试配置