問題描述
利用Vue做項目過程中,經常使用v-for渲染多個重複組件或dom元素,比如:傳遞json/字典,利用v-for遍歷json中的key和value,並渲染到頁面中,如下所示:
<!--element實現摺疊文件夾-->
<el-collapse ref="el_collaps_container" v-for="(value,key,index) in json_data" :key="index">
<!-- 這塊引入自定義組件 -->
<v-fold-file :fold_name="key" :fold_content="value"></v-fold-file>
</el-collapse>
然而,v-for在設計過程中,無法實現對數據的雙向綁定,也就是說,當json_data中的key或value改變時,默認data中的json_data屬性值可以改變,但是頁面內容還是之前組件第一次渲染出來的結果,無法實現實時刷新。
解決方案
Vue中,v-if是條件渲染,每次狀態更新都會重新刪除或者創建元素,因此利用v-if可以實現template中代碼的局部刷新(先刪除,再創建),但v-if有較高的切換性能消耗。
Vue官方中不推薦v-for和v-if在同一標籤中共同使用。因此,給上述示例代碼外面加上一層div,file_is_show爲true時創建,爲false時銷燬。如下所示:
<div class="figure_main" v-if="file_is_show">
<!-- v-for無法實現雙向綁定,藉助v-if重新渲染組件,實現v-for數據的動態更新 -->
<!--摺疊文件夾-->
<el-collapse ref="el_collaps_container" v-for="(value,key,index) in json_data" :key="index">
<!-- 這塊引入自定義組件 -->
<v-fold-file :fold_name="key" :fold_content="value"></v-fold-file>
</el-collapse>
</div>
監聽json_data數據改變,若json_data改變,元素先銷燬,再創建,實現頁面的局部刷新。
watch: {
// 監聽json數據變化,重新渲染文件夾內容
json_data(newVal) {
this.file_is_show = false
if (true) {
this.$nextTick(()=>{ // $nextTick 是在 DOM 更新循環結束之後執行延遲迴調
this.file_is_show = true
})
}
}
}
搞定!
注意:
- this.$nextTick是在DOM更新之後纔會調用裏面的內容。
- 如果不加這句話,json_data 改變,file_is_show先false,然後馬上更新爲true。而原本file_is_show就是true,所以DOM不會實現刷新。
- nextTick的使用可以在dom銷燬之後再執行回調函數(創建功能),這樣才能達到銷燬->創建,達到局部更新的功能。