【问题标题】:How do I trigger a hidden Quasar q-file input from an external q-btn?如何从外部 q-btn 触发隐藏的 Quasar q-file 输入?
【发布时间】:2022-07-03 02:43:43
【问题描述】:

我有一个用于选择图像文件的q-file 元素和一个用于显示图像的q-img 元素。

我不喜欢q-file的输入样式,所以我想隐藏它并从外部q-btn触发图片上传。

但我不知道如何从外部q-btn 触发q-file

const { ref } = Vue
const app = Vue.createApp({
  setup () {
  
    const image = ref(null);
    const imageUrl = ref('');
    
    const handleUpload = () => {
      if (image.value) {
        imageUrl.value = URL.createObjectURL(image.value);
      }
    }
    
    const handleUploadBtnClick = () => {
      // Somehow trigger the hidden q-file selection window
    }
    
    return {
      image, imageUrl, handleUpload
    }
  }
})

app.use(Quasar)
app.mount('#q-app')
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet" type="text/css">
<link href="https://cdn.jsdelivr.net/npm/quasar@2.4.13/dist/quasar.prod.css" rel="stylesheet" type="text/css">
<div id="q-app">
  <div>
    <q-file
      style="display: none"
      v-model="image"
      @update:model-value="handleUpload()"
   ></q-file>
  </div>
  <div>
    <q-btn
      type="button"
      label="Upload Photo"
      @click="handleUploadBtnClick"
   ></q-btn>
  </div>
  <div>
    <q-img
      :src="imageUrl"
      spinner-color="white"
      style="height: 140px; max-width: 150px"
    ></q-img>
  </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/quasar@2.4.13/dist/quasar.umd.prod.js"></script>

【问题讨论】:

    标签: vuejs3 quasar-framework


    【解决方案1】:

    您可以创建 refq-file ,然后从 q-btn 使用 file.value.pickFiles() 调用它

    const { ref, onMounted } = Vue
    const app = Vue.createApp({
      setup () {
      
        const image = ref(null);
        const imageUrl = ref('');
        const file = ref(null)
        
        const handleUpload = () => {
          if (image.value) {
            imageUrl.value = URL.createObjectURL(image.value);
          }
        }
        
        const handleUploadBtnClick = () => {
          file.value.pickFiles()
        }
        
        return {
          image, imageUrl, handleUpload, handleUploadBtnClick, file
        }
      }
    })
    
    app.use(Quasar)
    app.mount('#q-app')
    <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet" type="text/css">
    <link href="https://cdn.jsdelivr.net/npm/quasar@2.4.13/dist/quasar.prod.css" rel="stylesheet" type="text/css">
    <div id="q-app">
      <div>
        <q-file
          style="display: none"
          v-model="image"
          @update:model-value="handleUpload"
          ref="file"
       ></q-file>
      </div>
      <div>
        <q-btn
          type="button"
          label="Upload Photo"
          @click="handleUploadBtnClick"
       ></q-btn>
      </div>
      <div>
        <q-img
          :src="imageUrl"
          spinner-color="white"
          style="height: 140px; max-width: 150px"
        ></q-img>
      </div>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@2.4.13/dist/quasar.umd.prod.js"></script>

    【讨论】:

    • 这行得通,但我在 file.value.pickFiles() 上遇到 EsLint 错误,说 Unsafe call of an 'any' typed value.Property 'pickFiles' does not exist on type 'never'.。我试图通过像const file: Ref&lt;HTMLDivElement | null&gt; = ref(null); 那样键入模板引用来修复它。那没有用。现在我收到Unsafe call of an 'any' typed value.Property 'pickFiles' does not exist on type 'HTMLDivElement'. 错误。看来我需要正确输入 q-file 模板引用,但我不知道如何。有任何想法吗?我不想禁用 EsLint 错误,而是修复它们。
    • @TinyTiger 对不起,我不知道打字稿 :(
    【解决方案2】:

    嗨 @TinyTiger 我正在使用 Script Setup 和 TypeScript 搜索相同的内容,并在 Yusuf Kandemir 的帮助下结束了它的实现。

    <template>
      <q-card>
        <q-avatar
          color="red"
          v-on:click="selectFile()"
        >
          <q-img
            v-bind:src="img"
            v-bind:fit="'contain'"
            v-bind:ratio="1"
          />
        </q-avatar>
    
        <q-file
          ref="fileRef"
          v-model="fileModel"
          style="display: none"
          v-bind:max-files="1"
          accept="image/*"
          v-on:update:model-value="fileOnUpdate"
        />
      </q-card>
    </template>
    
    <script setup lang="ts">
    import { Ref, ref, onUnmounted } from 'vue'
    import { QFile } from 'quasar'
    
    const fileModel = ref<File>()
    const fileRef = ref() as Ref<QFile>
    const img = ref<string>()
    
    function selectFile() {
      fileRef.value.pickFiles()
    }
    
    function fileOnUpdate(selectedFile: File) {
      if (img.value) {
        URL.revokeObjectURL(img.value)
      }
      img.value = URL.createObjectURL(selectedFile)
    }
    
    onUnmounted(() => {
      if (img.value) {
        URL.revokeObjectURL(img.value)
      }
    })
    </script>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-28
      • 2023-01-30
      • 2016-10-05
      • 1970-01-01
      • 1970-01-01
      • 2021-11-26
      • 1970-01-01
      相关资源
      最近更新 更多