一、組件直接傳值
大家都知道父子組件傳值的方案,有以下幾個,不再詳細敖述
Props:父組件向子組件傳遞數據
$emit:子組件通過自定義事件向父組件傳遞數據
.sync修飾符:一個方便且強大的工具,可以簡化父子組件之間的雙向數據綁定,用于創建雙向綁定prop的修飾符,它允許子組件更新父組件的prop值,實現父子組件之間的雙向數據同步(如果不想使用事件),
.sync
修飾符的工作原理主要基于Vue.js的事件機制和prop傳遞機制Vuex進行狀態管理:應用提供了一種高效、清晰的狀態管理方案。通過集中式存儲管理、可預測的狀態變化、組件間的解耦以及方便的調試工具等特性,Vuex極大地簡化了應用程序的狀態管理。
provide/inject:是Vue.js中一種強大的機制,用于實現跨組件的數據共享和方法傳遞。它們能夠有效地避免繁瑣的props傳遞,提升組件間通信的靈活性和代碼的可維護性。然而,在使用時需要注意響應性問題、命名沖突以及性能開銷等細節。
Bus事件:Bus事件適用于簡單的場景或臨時解決方案,如果在組件銷毀后沒有移除事件監聽器,可能會導致內存泄漏。因此,在組件銷毀之前,應該使用
$off
方法來移除事件監聽器。refs或parent/$children訪問組件實例,父組件可以通過$refs直接訪問子組件的數據或方法;父組件可以通過children訪問子組件,子組件可以通過parent訪問父組件,從而實現父子組件之間的數據傳遞。但這種方式會破壞組件的封裝性和獨立性,因此應盡量避免過多使用。
二、?子組件改變父組件的值
子組件通過自定義事件向父組件傳遞數據,來讓父組件改變值,是正規使用,,其中.sync修飾符同步父組件值,是綜合版本,不過有以下兩種情況是不被推薦,尤其直接改變非對象屬性
- 子組件直接改變了父組件里面的對象:因為是對象里面的屬性,沒有直接觸發該對象屬性的 setter,只是在修改對象內部的引用,而這個內部引用并沒有被 Vue 的響應式系統所追蹤。因此,從技術上講,Vue 不知道這個內部屬性已經被修改,也就不會觸發視圖更新,也就不會報錯。(不會報錯)
- 直接修改父組件非對象屬性就會直接觸發 setter引發報錯Avoid mutating a prop...(報錯)
?父組件
<template><div><child-component :parentMessage="parentMessage" :form="form" @setParentMessage="setParentMessage" :form.sync="form"></child-component></div>
</template><script>
export default {data() {return {parentMessage: 'Hello from parent!',form:{user:'默認'}};},methods: {setParentMessage(msg) {this.parentMessage = msg//推薦}}
}
</script>
子組件
<template><div><p @click="sendUpdate">{{ parentMessage }}</p></div>
</template><script>
export default {props: {parentMessage: String,form: Object},methods: {sendUpdate(data) {this.form.us='不報錯'//只是在修改對象內部的引用,而這個內部引用并沒有被 Vue 的響應式系統所追蹤。因此,從技術上講,Vue 不知道這個內部屬性已經被修改,也就不會觸發視圖更新,也就不會報錯。this.parentMessage='報錯'//Avoid mutating a prop...//推薦:子組件通過自定義事件向父組件傳遞數據,來讓父組件改變值,是正規使用this.$emit('setParentMessage', '自定義事件傳遞數據');//推薦:.sync修飾符同步父組件值const form = { ...this.form };form.us = '.sync修飾符同步父組件值';this.$emit('update:form', form);//當然這樣做可能會使代碼變得難以理解和維護,特別是在大型應用程序中。//更好的做法是遵循Vue的最佳實踐,即不要直接修改prop。this.form.us = '.sync修飾符同步父組件值';this.$emit('update:form', this.form);}}
}
</script>