vue.js - 在 Vue 组件中自动重新加载图像
问题描述
我有一个用于货物操作的简单组件。在这个组件中,我可以创建商品并更改它们的图像。当我更改某个商品的图像时,后端应用程序会执行替换具有相同名称的现有图像,因此图像 URL 不会更改。因此,在我刷新页面之前,页面上的图像不会重新加载。
获得成功的服务器响应后,如何强制重新加载图像?
那是很好的组件来源:
<template>
<div class="container">
<h3 class="mt-5">Goods</h3>
<div class="row mt-5">
<div class="col-md-12">
<div class="card">
<div class="card-header align-middle">
<div class="card-tools">
<button class="btn btn-success btn-sm" v-b-modal.create-good-modal>Add</button>
</div>
</div>
<div class="card-body table-responsive p-0">
<table class="table table-hover text-center">
<thead>
<tr>
<th>ID</th>
<th>Image</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr v-for="good in goods" :key="good.id">
<td class="align-middle">{{ good.id }}</td>
<td class="align-middle">
<img class="img-thumbnail" width="60" :src="goodImageUrl(good.image)"
v-b-modal.change-good-image-modal @click="changeGoodImage(good.id)" />
</td>
<td class="align-middle">{{ good.name }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<b-modal ref="createGoodModal" id="create-good-modal" title="New good" hide-footer @show="resetCreateGoodModal"
@hide="resetCreateGoodModal">
<b-form @submit="createGood" class="w-100">
<b-form-group id="form-create-good-name-group" label="Name" label-for="form-create-good-name-input">
<b-form-input id="form-create-good-name-input" type="text" v-model="createGoodForm.name" required
placeholder="Good name">
</b-form-input>
</b-form-group>
<b-form-group id="form-create-good-image-group">
<b-form-file v-model="createGoodForm.image" required :state="Boolean(createGoodForm.image)"
placeholder="Choose good image">
</b-form-file>
<div class="mt-3">Selected image: {{ createGoodForm.image ? createGoodForm.image.name : '' }}</div>
</b-form-group>
<b-button type="submit" variant="primary">Create</b-button>
</b-form>
</b-modal>
<b-modal ref="changeGoodImageModal" id="change-good-image-modal" title="Change good image"
@hide="resetChangeGoodImageModal" hide-footer>
<b-form @submit="updateGoodImage" class="w-100">
<b-form-group id="form-change-good-image-group">
<b-form-file v-model="changeGoodImageForm.image" required :state="Boolean(changeGoodImageForm.image)"
placeholder="Choose good image">
</b-form-file>
<div class="mt-3">Selected file: {{ changeGoodImageForm.image ? changeGoodImageForm.image.name : ''
}}
</div>
</b-form-group>
<b-button type="submit" variant="primary">Save</b-button>
</b-form>
</b-modal>
</div>
</template>
<script>
import {objectToFormData} from "object-to-formdata";
export default {
data() {
return {
goods: [],
createGoodForm: new Form({
name: "",
image: null
}),
changeGoodImageForm: new Form({
id: {},
image: null
})
};
},
methods: {
getGoods() {
axios
.get("goods/list")
.then(response => {
this.goods = response.data;
})
.catch(error => {
console.error(error);
});
},
createGood() {
this.createGoodForm
.post("goods", {
transformRequest: [
function (data, headers) {
return objectToFormData(data);
}
]
})
.then(() => {
this.$refs.createGoodModal.hide();
this.getGoods();
})
.catch(error => {
console.log(error);
});
},
changeGoodImage(id) {
this.changeGoodImageForm.id = id;
},
updateGoodImage() {
this.changeGoodImageForm
.post("goods/" + this.changeGoodImageForm.id + "/image", {
transformRequest: [
function (data, headers) {
return objectToFormData(data);
}
]
})
.then(() => {
this.$refs.changeGoodImageModal.hide();
this.getGoods();
})
.catch(error => {
console.log(error);
});
},
goodImageUrl(filename) {
return "http://127.0.0.1:8098/api/img/goods/" + filename;
},
resetCreateGoodModal() {
this.createGoodForm.reset();
},
resetChangeGoodImageModal() {
this.changeGoodImageForm.reset();
}
},
created() {
this.getGoods();
}
};
</script>
解决方案
我的建议只是将随机缓存破坏器附加到图像 url - 服务器将忽略的查询参数将强制浏览器获取新图像。这假设您的后端不会拒绝请求,但大多数时候这种方法有效。类似的东西/myimage.png?cacheBuster=<somethingRandom>
。
请注意,在下面的代码段中,实际上不会加载新的猫图像,因为该服务器每次都没有新图像。这只是一个演示。
为了减少技术债务并帮助记录/调试,我建议做一些额外的工作并让您的 api 返回一个您可以附加的新图像版本,而不仅仅是粗略的缓存崩溃。但这是一个更大的项目。例子/myimage.png?version=2
const originalSource = 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/69/June_odd-eyed-cat_cropped.jpg/120px-June_odd-eyed-cat_cropped.jpg';
var app = new Vue({
el: '#app',
data() {
return {
imageSource: originalSource
}
},
methods: {
bustThatCache() {
this.imageSource = `${originalSource}?cacheBust=${Math.random()}`
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<p>Image Src:{{imageSource}}</p>
<img :src="imageSource"></img>
<button @click="bustThatCache">Load new image</button>
</div>
推荐阅读
- javascript - 在 windows10 中安装 Chilkat-11 后出错
- python - 如何将更新操作广播到numpy数组
- c# - PhilipsHue XY Bri 转 RGB(不含 Philips Hue SDK)
- powershell - 等待 Active Directory 身份验证 URL 列表在 Powershell Azure 函数中更新
- c# - 在字符串数组c#中使用“foreach”
- http - Postman 在使用 Rossum API 时显示 CSRF 错误
- r - Shinyapps.io 应用程序部署失败。如何调试不明确的错误日志?
- javascript - 如何使用codeigniter在MYSQL数据库中使用数组索引上传文件
- python-3.x - 如何在单独的作业中或异步地为烧瓶 request.files.getlist('images') 中的多个图像实现 image.read()
- c - 尽管没有到达字符串的末尾,strtok 返回 NULL