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 单元测试配置

从 Quasar Framework 的 assets 目录加载一个 web worker

禁用 q-item 上的突出显示(Quasar Framework)