上传图片时如何在vue组件上自动更新图片?
Posted
技术标签:
【中文标题】上传图片时如何在vue组件上自动更新图片?【英文标题】:How can I update image automatic on vue component when I upload the image? 【发布时间】:2018-08-15 05:53:45 【问题描述】:我的 vue 组件是这样的:
<template>
<section>
...
<img class="media-object" :src="baseUrl+'/storage/banner/thumb/'+photo" >
...
</section>
</template>
<script>
export default
props: ['banners'],
data()
return
baseUrl: App.baseUrl,
bannerId: this.banners.id,
photo: this.banners.photo // result : chelsea.png
,
methods:
onFileChange(e)
let files = e.target.files,
reader = new FileReader(),
formData = new FormData(),
self = this
formData.append('file', files[0])
formData.append('banner_id', this.bannerId)
axios.post(window.App.baseUrl+'/admin/banner/upload-image',
formData,
headers:
'Content-Type': 'multipart/form-data'
).then(function(response)
if(response.data.status == 'success')
self.photo = response.data.fileName // result : chelsea.png
)
.catch(function(error)
console.log('FAILURE!!')
)
,
...
</script>
:src
的结果:\my-app\storage\app\public\banner\thumb\chelsea.png
当我上传图片时,它会调用 onFileChange 方法。并且进程上传将在后端继续。它成功上传到文件夹中。并且响应将返回相同的文件名。所以response.data.fileName
的结果是chelsea.png
我的问题是:上传图片时不会自动更新图片。当我刷新页面时,图像更新了
为什么我上传图片时图片没有自动更新/更改?
【问题讨论】:
【参考方案1】:尝试绑定完整照片的路径:
<template>
<section>
...
<img v-if="photoLink" class="media-object" :src="photoLink" >
<p v-text="photoLink"></p>
...
</section>
</template>
<script>
export default
props: ['banners'],
data()
return
baseUrl: App.baseUrl,
bannerId: this.banners.id,
photo: this.banners.photo, // result : chelsea.png
photoLink: App.baseUrl + '/storage/banner/thumb/' + this.banners.photo
,
methods:
onFileChange(e)
let files = e.target.files,
reader = new FileReader(),
formData = new FormData(),
self = this
formData.append('file', files[0])
formData.append('banner_id', this.bannerId)
axios.post(window.App.baseUrl+'/admin/banner/upload-image',
formData,
headers:
'Content-Type': 'multipart/form-data'
).then(function(response)
if(response.data.status == 'success')
// self.photo = response.data.fileName // result : chelsea.png
console.log('>>>INSIDE SUCCESS');
self.photoLink = self.baseUrl + '/storage/banner/thumb/' + response.data.fileName;
)
.catch(function(error)
console.log('FAILURE!!')
)
,
...
【讨论】:
你能通过打印console.log('>>>INSIDE SUCCESS');
确保'success'里面的代码正在执行吗?还有<p v-text="photoLink"></p>
正在更新新的photoLink?
console.log('>>>INSIDE SUCCESS');
的结果显示在控制台上。但是图片没有更新
<p v-text="photoLink"></p>
更新了吗?
是的。它正在更新。但是图片仍然没有更新
这似乎是因为文件名与响应中的文件名相同。文件名:chelsea.png
。如果文件名与响应不同,它可以工作。但是这里我希望文件名是一样的【参考方案2】:
只需使用计算属性,sn-p 下面使用
getImageUrl
来获取更新的路径。我添加了按钮来触发所提供数据的模拟变化。
new Vue(
el: "#app",
data:
baseUrl: 'baseURl', //dummy
bannerId: '', //dummy
photo: 'initPhoto.png' // dummy
,
computed:
getImageUrl: function()
return this.baseUrl + '/storage/banner/thumb/' + this.photo;
,
methods:
mimicOnChange: function()
this.photo = "chelsea.png"
)
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue.js"></script>
<div id="app">
<span> getImageUrl </span>
<br/>
<button @click="mimicOnChange">
On change trigger
</button>
</div>
在您上面的代码中,只需将计算直接用于您的 src 属性:
<img class="media-object" :src="getImageUrl" >
【讨论】:
【参考方案3】:您的图像由浏览器缓存。尝试向图像添加任何标签,例如: chelsea.png?t=
【讨论】:
是的,有时它会给我相同的图像,但刷新后它改变了,我如何在不重命名图像本身的情况下修复它? 通常,后端会为我们提供 MIME 类型的图像路径,例如 /image/12334。不返回 image.png。【参考方案4】:我通过执行以下操作修复了它,请注意我在照片 url 的末尾添加了一个名为 rand
的变量用于缓存清除。当您从服务器获得正确响应时,只需将该变量更改为唯一的值(在本例中为时间戳),瞧!您的图像将刷新。
<template>
<img class="media-object" :src="baseUrl+'/storage/banner/thumb/'+photo + '?rand=' + rand" >
</template>
<script>
export default
data()
return
rand: 1
,
methods:
onFileChange(e)
...
axios.post(url,formData).then(function(response)
if(response.data.status == 'success')
self.rand = Date.now()
)
,
...
【讨论】:
【参考方案5】:上面提供的答案是计算属性,因为这些属性被设计为响应式的,但是当涉及到异步时,最好使用 promises / observables。但是,如果您决定不使用并且仍然遇到问题,那么您可以使用加载属性,例如下面示例中的 loading
属性来操作 DOM,即在您启动异步 (axios) 时使用 v-if 删除 DOM .获取并设置图像,然后使用this.loading = true;
恢复 DOM 元素。这会强制渲染 DOM,从而强制计算属性。
<template>
<section>
<div v-if="!loading">
<img class="media-object" :src="getPhoto" : >
</div>
<div v-if="loading">
<!-- OR some spinner-->
<div>Loading image</div>
</div>
</section>
</template>
<script>
export default
props: ['banners'],
data()
return
loading: false,
baseUrl: App.baseUrl,
bannerId: this.banners.id,
photo: // result : chelsea.png
,
computed:
getPhoto()
return App.baseUrl + '/storage/banner/thumb/' + this.photo.fileName;
,
getAlt()
return photo.alt;
,
,
methods:
onFileChange(e)
let files = e.target.files,
reader = new FileReader(),
formData = new FormData(),
self = this
// Set loading to true
this.loading = true;
formData.append('file', files[0])
formData.append('banner_id', this.bannerId)
axios.post(window.App.baseUrl+'/admin/banner/upload-image',
formData,
headers:
'Content-Type': 'multipart/form-data'
).then(function(response)
if(response.data.status == 'success')
self.photo = response.data.fileName // result : chelsea.png
this.loading = false;
)
.catch(function(error)
console.log('FAILURE!!')
)
,
...
</script>
【讨论】:
【参考方案6】:我遇到了同样的问题,在输入后插入相同的图像不会触发任何操作。我通过清除输入来修复它。
clearInput(e)
e.target.value = '';
,
【讨论】:
以上是关于上传图片时如何在vue组件上自动更新图片?的主要内容,如果未能解决你的问题,请参考以下文章