v-bind="$attrs" 可以將父組件傳遞的所有屬性綁定到子組件中,但是這種方式只能提供屬性的綁定,事件處理程序并不能綁定到子組件中。此時就需要使用 $listeners 和 $attrs 結合使用。
首先,在子組件中使用 $listeners 來綁定所有的事件處理程序:
computed: { listeners() { // 過濾掉屬性名以 'on-' 開頭的屬性,剩下的都是事件處理程序 const { on, ...otherAttrs } = this.$attrs const listeners = {} for (const eventName in on) { listeners[eventName] = ($event) =>{ // 調用父組件傳遞的事件處理程序,并將 $event 傳遞進去 this.$emit(eventName, $event) } } return listeners } }
上述代碼使用了 computed 屬性,將所有 $attrs 中以 'on-' 開頭的屬性過濾掉,然后遍歷剩下的事件處理程序,并將其賦值給 listeners 對象。此時,我們需要使用 v-on 指令來將 listeners 中的事件處理程序綁定到子組件中:
{{ text }}
這里我們使用 v-on 指令將 listeners 對象中的事件處理程序綁定到子組件中。需要注意的是,在使用 v-bind="$attrs" 和 v-on="listeners" 的時候,$attrs 中的所有屬性都被綁定到了子組件上,包括不以'on-'開頭的屬性。
上述代碼中子組件接收了一個 $attrs 對象,可以通過 this.$attrs 獲取到該對象。而 $listeners 對象則包含了父組件傳遞進來的事件處理程序。使用這兩者配合工作,就可以完美地將屬性和事件處理程序綁定到子組件中,從而實現高效的組件復用。