在 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>
(在看到完整代码后,我建议将逻辑拆分成更小的组件)
我在 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>
(在看到完整代码后,我建议将逻辑拆分成更小的组件)