问题描述:
在上传视频到服务器后,动态更新video的src属性时,video没有显示视频内容,再当前页面视图发生改变后,video才显示出内容。
html部分:
<el-upload class="avatar-uploader"
:action="videoUploadUrl"
:file-list="videofileList"
:limit="1"
v-bind:data="{FoldPath:'上传目录',SecretKey:'安全验证'}"
:on-progress="uploadVideoProcess"
:on-success="handleVideoSuccess"
:before-upload="beforeUploadVideo"
:on-remove="removeVideo">
<video v-if="editForm.videoUrl" ref="video"
:src="editForm.videoUrl"
class="avatar video-avatar videoBox"
controls="controls"> 您的浏览器不支持视频播放
</video>
<i v-if="!editForm.videoUrl" class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
js部分
//视频成功上传的回调
handleVideoSuccess(response, file, fileList){
this.videoFlag = false;//隐藏进度条
this.videoUploadPercent = 0;//进度重置为0
if (file.status == 'success' ) {
let videoId = JSON.parse(response.data).fileId;//保存video的id,用于拼接
this.$api.getPublicFileUrl().then(res => {
this.publicFileUrl = res.data.data
this.editForm.videoUrl = this.publicFileUrl + '/' + videoId
console.log(this.editForm.videoUrl)
})
} else {
this.$message.info("上传失败,请重新上传");
}
},
上传之前:
上传之后(文件列表中显示有文件,但video却没有显示,查看dom显示没有src属性)
再更新一下视图,例如点击一个多选框后,video能正常的显示出来
再复制后打印其this.editForm.videoUrl,显示确实有值的,但是video没有视频显示,猜测是v-if=”editForm.videoUrl”的问题。
经过测试在页面上显示{{!editForm.videoUrl}},猜测是vue没有检测第一时间检测到this.editForm.videoUrl的变化,百度后了解到:vue不能检测到对象属性的添加或删除。
引用官网的解释:官网——深入响应式原理中介绍到:受现代 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。
问题分析:由于第一时间editForm没有videoUrl的属性,再上传之后的回调函数中直接为其赋值:
this.editForm.videoUrl = this.publicFileUrl + '/' + videoId
Vue未能检测到添加属性videoUrl的变化,没有按想象中的渲染videoUrl数据,再下一次试图更新后,才更新数据。
解决方案:使用$set为对象设置属性和属性值
this.$set(this.editForm,"videoUrl",this.publicFileUrl + '/' + videoId)
使用this.$set()便能为editForm添加属性videoUrl,也能使vue正常渲染数据。
//视频成功上传的回调
handleVideoSuccess(response, file, fileList){
this.videoFlag = false;//隐藏进度条
this.videoUploadPercent = 0;//进度重置为0
if (file.status == 'success' ) {
console.log(response)
let videoId = JSON.parse(response.data).fileId;//保存video的id,用于拼接
this.$api.getPublicFileUrl().then(res => {
this.publicFileUrl = res.data.data
this.$set(this.editForm,"videoUrl",this.publicFileUrl + '/' + videoId)
console.log(this.editForm.videoUrl)
})
} else {
this.$message.info("上传失败,请重新上传");
}
},
如此便可以解决遇到的问题: