Avoid mutating a prop directly since the value wi... 的錯誤處理

在vue.js中,在自定義一個組件的時候,可能會有這樣的問題,當我們子組件中修改props中的值的時候,會有這樣的錯誤提示:
Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value.
直譯爲:不要直接修改一個prop屬性的值,因爲這個值隨時都可能在父組件重新渲染時被覆寫。解決方案是,將prop屬性的值賦給data或computed屬性的值。
那麼,具體我們該怎麼做呢?首先,看一下vue.js的官方文檔

官方文檔

所有的 prop 都使得其父子 prop 之間形成了一個單向下行綁定:父級 prop 的更新會向下流動到子組件中,但是反過來則不行。這樣會防止從子組件意外改變父級組件的狀態,從而導致你的應用的數據流向難以理解。

額外的,每次父級組件發生更新時,子組件中所有的 prop 都將會刷新爲最新的值。這意味着你不應該在一個子組件內部改變 prop。如果你這樣做了,Vue 會在瀏覽器的控制檯中發出警告(警告的內容就是上述那段英文)。

這裏有兩種常見的試圖改變一個 prop 的情形:

這個 prop 用來傳遞一個初始值;這個子組件接下來希望將其作爲一個本地的 prop 數據來使用。在這種情況下,最好定義一個本地的 data 屬性並將這個 prop 用作其初始值:

props: ['initialCounter'],
data: function () {
  return {
    counter: this.initialCounter
  }
}

這個 prop 以一種原始的值傳入且需要進行轉換。在這種情況下,最好使用這個 prop 的值來定義一個計算屬性:

props: ['size'],
computed: {
  normalizedSize: function () {
    return this.size.trim().toLowerCase()
  }
}

注意:在 JavaScript 中對象和數組是通過引用傳入的,所以對於一個數組或對象類型的 prop 來說,在子組件中改變這個對象或數組本身將會影響到父組件的狀態。

更進一步

官方文檔中,有這樣的一段描述:注意:在 JavaScript 中對象和數組是通過引用傳入的,所以對於一個數組或對象類型的 prop 來說,在子組件中改變這個對象或數組本身將會影響到父組件的狀態。意思是說:如果你的prop的值得類型不是js的基本類型(數值、字符串、null、undefined、布爾值),而是引用類型(對象、數組、函數、正則…)的話,就不能直接進行賦值了。那如何解決呢?
答案是:使用深拷貝(deepCopy)來代替直接賦值,具體什麼是js的深拷貝,請自行查閱。同樣是官方的例子,如果initialCounter是一個對象的話,可以這樣賦值:

props: ['initialCounter'],
data: function () {
  return {
    counter: JSON.parse(JSON.stringify(this.initialCounter))
  }
}

但是這樣的方式有巨大的缺陷,只適用於一些簡單的場景。想更深入的瞭解深拷貝,請自行查閱。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章