在 vue js 中获取图像宽度和高度 50% 的时间

Get image width and height working 50% of the time in vue js

我在 Vue js 的视图文件中有这个结构(已编辑):

<template>
    <div>
        <h1>{{quiz.name}}</h1>
    </div>
    <div class="quizForm">
        <div class="quizQuestContainer">
            <div class="quizQuestions" v-for="(question, index) in quiz.questions"
            :key = index >
            <div v-if="index === questionIndex">
                <h2>{{ question.text }}</h2>
                <ol>
                    <li v-for="(response, index) in question.responses"
                        :key = index
                    >
                    <label>
                       
                        <input type="radio" 
                            :value="[response.res_value === question.solution]"
                            :name="index" 
                        > {{response.res_text}}
                    </label>
                    </li>
                </ol>
                <button v-if="questionIndex > 0" v-on:click="prev">
                    prev
                </button>
                <button v-on:click="next">
                    next
                </button>
            </div>
        </div>
        <div v-if="questionIndex === quiz.questions.length">
            <h2> Quiz finished</h2>
        </div>
    </div>
    <div class="quizImage">
            <div class="ImageArea">
                <img :src="imageCrop(quiz.iiif)">
                <br/>    
            </div>
</template>
<script>
    import sourceData from '@/data.json'

    export default {
      props:{
        id: {type: String, required: true}
      },
      data(){
        return {
            questionIndex: 0,

        }
      },

      computed:{
        quiz(){
            return sourceData.quizzes.find(quiz =>quiz.id === parseInt(this.id))
            },
        },
       methods: {
         // Go to next question
       next: function() {
         this.questionIndex++;
       },
       // Go to previous question
       prev: function() {
           this.questionIndex--;
       },

       imageCrop: function(iiif) { 
          let image = new Image();
          image.src = iiif; 
          let width =  image.width; 
          let height = image.height;
          return image.src + " this is width " + width + " and this is height " + height
       }
</script>

有时我得到正确的高度和宽度,但有时我得到 0 和 0。是否存在一些缓存问题?方法是执行此操作的正确方法吗?我是Vue的新手,所以不是很了解它是如何工作的。

编辑:如果我使用

 image.onload = () => {
       let height = image.height;
       let width = image.width;
       return image.src + " this is width " + width + " and this is height " + height
 }

页面上没有显示任何内容。我试图像这样进行错误处理:

nameError: function(){
        try {
            const error = new Error();
            return error.message;
        } catch (ex) {
            return ex.message;
        }

并在 DOM:

中生成一个事件

const invoker = (e) => { // async edge case #6566: inner click event triggers patch, event handler // attached to outer element during patch, and triggered again. This // happens because browsers fire microtask ticks between event propagation. // the solution is simple: we save the timestamp when a handler is attached, // and the handler would only fire if the event passed to it was fired // AFTER it was attached. const timeStamp = e.timeStamp || _getNow(); if (skipTimestampCheck || timeStamp >= invoker.attached - 1) { callWithAsyncErrorHandling(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* NATIVE_EVENT_HANDLER */, [e]); }

数据JSON是这样的:

{
    "quizzes": [
      {
        "name": "Quiz A",
        "slug": "quiz-1",
        "image": "D000533S_AlbiniW_ST40.jpg",
        "iiif": "https://gallica.bnf.fr/iiif/ark:/12148/btv1b9042253v/f1/full/,550/0/native.jpg", 
        "id": 1,
        "description":
          "First quiz",
        "questions": [
            {
              "text": "Question 1",
              "responses": [
                {"res_text": "Wrong",
                  "res_value": "a"
                }, 
                {"res_text": "Right",
                  "res_value": "b"
                }
              ],
              "solution": "a"
            }, 
            {
              "text": "Question 2",
              "responses": [
                {"res_text": "Right",
                  "res_value": "a"
                }, 
                {"res_text": "Wrong",
                  "res_value": "b"
                }
              ],
              "solution": "b"
          }
        ]
      },

等等

正如@theshark 在评论中指出的那样,创建图像以检索其尺寸是一个异步过程。据我所知,您将无法在渲染中使用这种方法的结果。

不清楚您要实现的目标是什么,但最简单的方法是在您的 imageCrop 方法获取维度后将其存储在组件的数据中。不必在模板中调用此方法,而是在 created 挂钩中调用。

您可以直接在模板中绑定组件的数据:

<template>
  <div>
    <div>
      <h1>{{quiz.name}}</h1>
    </div>
    <div class="myImageData">
       {{ src }} this is width {{ width }} and this is height {{ height }}
    </div>
    <div class="quizImage">
        <div class="ImageArea">
          <img :src="src">
          <br/>    
        </div>
    </div>
    <button @click="prev">⬅️</button>
    <button @click="next">➡️</button>
  </div>
</template>

<script>
import sourceData from '@/data.json'
export default {
 props:{
    id: {type: String, required: true}
  },
  data() {
    return {
      src: "",
      width: 0,
      height: 0,
      questionIndex: 0,
    }
  },
  computed:{
    quiz(){
      return sourceData.quizzes.find(quiz => quiz.id === this.questionIndex);
    },
  },
  updated() {
    this.imageCrop();
  },
  created() {
    this.questionIndex = parseInt(this.id);
    this.imageCrop();
  },
  methods: {
   next: function() {
     this.questionIndex++;
   },
   prev: function() {
     this.questionIndex--;
   },
   imageCrop: function() {
      const iiif = this.quiz.iiif;
      let image = new Image();
      image.onload = (event) => {
        this.width = event.target.width;
        this.height = event.target.height;
        this.src = event.target.src;
      }
      image.src = iiif; 
    }
  }
}
</script>

(在看到完整代码后,我建议将逻辑拆分成更小的组件)