今天在寫代碼時(shí)遇到了一個(gè)大坑,需求是要實(shí)現(xiàn)文件的下載并且展示下載的實(shí)時(shí)進(jìn)度

所以需要結(jié)合webSocket實(shí)時(shí)返回下載進(jìn)度,然后把返回的數(shù)據(jù)實(shí)時(shí)渲染到頁面上,但是發(fā)現(xiàn)使用
this.$set方法并沒有生效。。。首先我們知道this.$set的用法,其實(shí)就是向響應(yīng)式對(duì)象中添加一個(gè)屬性,并且觸發(fā)試圖更新,舉一個(gè)簡單例子:
<template>
<div class="home">
<p>{{obj.age}}</p>
</div>
</template>
<script>
export default {
name: "HomeView",
components: {},
data() {
return {
obj:{
name:'xxx',
}
};
},
mounted() {
this.obj.age=20;
console.log(this.obj) //{name:'xxx',age:20}
},
methods: {},
};
執(zhí)行這段代碼會(huì)發(fā)現(xiàn)試圖上并沒有出現(xiàn)age的值,但是控制臺(tái)里可以打印出來,這就設(shè)計(jì)到ES5中的Object.defineProperty方法了,這個(gè)方法有一個(gè)缺點(diǎn)就是不能監(jiān)聽到對(duì)象或數(shù)組屬性的增加或刪除,就導(dǎo)致了這一現(xiàn)象的發(fā)生。
vue中的雙向數(shù)據(jù)綁定就是用這個(gè)方法實(shí)現(xiàn),vue在創(chuàng)建實(shí)例的時(shí)候,會(huì)遍歷data里的值,為對(duì)象的每個(gè)屬性加上getter和setter方法,一旦這些屬性對(duì)應(yīng)的值更新了就會(huì)去觸發(fā)對(duì)應(yīng)的視圖更新,而age這個(gè)屬性不是vue實(shí)例化的時(shí)候就擁有的屬性,所以vue并沒有對(duì)這個(gè)屬性進(jìn)行g(shù)etter和setter的監(jiān)聽,因此無法實(shí)現(xiàn)雙向綁定,也就無法更新視圖。
但是this.$set方法還有另一種情況,就是當(dāng)你要設(shè)置的key已經(jīng)存在于這個(gè)對(duì)象或數(shù)組中的時(shí)候,它只會(huì)更改data并不會(huì)為該key添加響應(yīng)檢測

所以頁面上的依賴downProgress的試圖就不會(huì)更新,解決這個(gè)問題的辦法就是在設(shè)置值之前先把這個(gè)屬性刪除掉,然后再進(jìn)行this.$set,


ok,完美解決~