之前寫的Vue項目,有個問題困擾了好久。新聞板塊有推薦、精華、最新等幾個Tab,設想通過切換Tab,改變路由參數(get/news/:tab)去獲取對應數據,然后渲染到頁面(用的是同一套組件),問題來了:當切換Tab時,數據並沒有更新,后來看了Vue-router官網,有這么一句話:提醒一下,當使用路由參數時,例如從 /user/foo 導航到 user/bar,原來的組件實例會被復用。因為兩個路由都渲染同個組件,比起銷毀再創建,復用則顯得更加高效。不過,這也意味着組件的生命周期鈎子不會再被調用。 意思很明顯了:雖然路由參數發生了變化,但組件還是那個組件,Vue生命周期也還沒結束,此時並不會刷新數據。(個人認為,開發spa頁面,一切都是以路由為起點的,路由變化,頁面跟着變化,復用組件竟然會影響到路由,很難受!!)
不過,官網也提出了相應的解決方案:復用組件時,想對路由參數的變化作出響應的話,你可以簡單地 watch(監測變化) $route 對象:
const User = { template: '...', watch: { '$route' (to, from) { // 對路由變化作出響應... } } }
今天,在逛社區的時候,又遇到這個‘’攔路虎‘’以及一個非常新穎的解決方案,相信不少人在看Vue官方文檔的時候,對這句話有過疑問:用 :key管理可復用的元素(這句話出自條件渲染 v-if部分),如何管理,官網也給了演示(我第一次看的時候,好像是沒有的例子的) 這個例子讓我對v-if又有了不同的看法:以前認為v-if是動態的生成/去除元素,仔細看例子,會發現:模板相同,會造成一種“復用”的感覺(v-if和v-else的模板是一樣一樣的),也就是說,數據更新之前,會先比較模板先后的異同,再決定是否跟新數據,並不是先更新數據,再刷新模板。 對:key的詳細解讀來自知乎:https://www.zhihu.com/question/61064119
上面的思考題其實跟我遇到的問題是一致的,自己進入了一個誤區:Vue是數據驅動的,這句話是絕對沒有問題的,但他不是‘金科玉律’,vue的底層實現應該是:通過比較模板先后的異同,再決定是否跟新數據(個人拙見,輕噴)。
回到正題,:key是用來阻止“復用”的。 Vue 為你提供了一種方式來聲明“這兩個元素是完全獨立的——不要復用它們”。只需添加一個具有唯一值的 key 屬性即可(Vue文檔原話)
那么,給<router-view></router-view>添加一個key,能不能解決這個問題呢?答案是可以的(廢話-_-||) 可以這樣來:
<router-view :key="key"></router-view> computed: { key() { return this.$route.name !== undefined? this.$route.name +new Date(): this.$route +new Date() } }
使用computed屬性和Date()可以保證每一次的key都是不同的,這樣就可以如願刷新數據了。
對這個問題的研究就先到這里了,以后遇到新的方案,會繼續補充
----2017.06.22 22:53
