上传图像时,如何在vue组件上自动更新图像?

时间:2018-03-07 07:48:36

标签: javascript vue.js vuejs2 image-uploading vue-component

我的vue组件是这样的:

<template>
    <section>
        ...
            <img class="media-object" :src="baseUrl+'/storage/banner/thumb/'+photo" alt="" width="64" height="64"> 
        ...
    </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

我的问题是:我上传时不会自动更新图像。刷新页面时,图像已更新

为什么上传图片时图片不会自动更新/更改?

6 个答案:

答案 0 :(得分:0)

尝试绑定完整照片的路径:

<template>
<section>
    ...
        <img v-if="photoLink" class="media-object" :src="photoLink" alt="" width="64" height="64"> 
        <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!!')
            })
        },
        ...
    }
}

答案 1 :(得分:0)

  

只需使用计算属性,使用下面的代码段getImageUrl来获取更新后的路径。我添加了按钮来触发对所提供数据的模仿更改。

&#13;
&#13;
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"
    }
  }
})
&#13;
<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>
&#13;
&#13;
&#13;

  

在上面的代码中,只需将计算机直接用于你的src属性:

<img class="media-object" :src="getImageUrl" alt="" width="64" height="64"> 

答案 2 :(得分:0)

您的图片由浏览器缓存。尝试将任何标记添加到图像,如: chelsea.pngΔT=

答案 3 :(得分:0)

我通过以下操作对其进行了修复,请注意,我在照片URL的末尾添加了一个名为rand的变量以清除缓存。当您从服务器获得正确的响应时,只需将该变量更改为唯一的变量(在本例中为时间戳)即可!您的图片会刷新。

<template>
    <img class="media-object" :src="baseUrl+'/storage/banner/thumb/'+photo + '?rand=' + rand" alt="" width="64" height="64"> 
</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()
                    }
                })
            },
        ...
    }

    }

答案 4 :(得分:0)

如上所述,答案是计算属性,因为这些属性被设计为可响应的,但是在异步方面,最好使用promise / observable。但是,如果您决定不使用并且仍然遇到问题,则可以使用loading属性,例如下面示例中的loading属性来操作DOM,即在启动异步时使用v-if删除DOM( axios)。获取并设置图像,然后使用this.loading = true;恢复DOM元素。这将强制DOM渲染,从而强制计算属性。


<template>
    <section>
        <div v-if="!loading">
            <img class="media-object" :src="getPhoto" :alt="getAlt" width="64" height="64">
        </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>


答案 5 :(得分:0)

我遇到了同样的问题,即在输入后插入相同的图像不会触发任何操作。我通过清除输入来解决它。

clearInput(e) {
  e.target.value = '';
},