vue extends繼承後怎麼注入虛擬DOM節點
1.需求
使用extends繼承一個組件並在上面做功能的修改和擴展,同時需要小小修改一部分的template。
2.extend原理
使用extends
時,你實際上是創建了一個新組件,它包含了父組件的所有選項和數據,但是你可以覆蓋或添加新的選項。
3.問題
修改通過extends
繼承的組件的template
並不簡單,因爲Vue的合併策略不會合並template
選項。如果你想修改父組件的template
,需要採取其他方法。
直接寫template的話會將原本的模板全部覆蓋掉,但是copy並重寫一次template又做了很多無用功顯得不夠優雅,也失去了繼承的意義。
4.解決
暫時沒有太完美的方法,目前可用的方案就是【劫持插槽】。
比如繼承過來的代碼中有一處具名插槽footer,我的需求是在這個位置添加上幾個按鈕,那麼我的代碼可以相下面這樣處理:
- 使用h函數將虛擬dom掛到footer插槽上
import basenewComponent from '***********'; export default { name: 'newComponent', extends: basenewComponent , methods:{ distribute(){}, }, render(h) { this.$slots.footer = [// 在這兒繪製的底部按鈕 h('el-button', { attrs: { type: 'primary', disabled: !this.canSubmit, }, on: {//事件 click: () => { this.distribute(false); }, }, }, '新按鈕1'), h('el-button', { on: { click: () => { this.distribute(true); }, }, }, '新按鈕2'), h('el-button', { on: { click: () => { this.visible = false; }, }, }, '取消'), ]; return basenewComponent.render.call(this, h); }, };
-
手動合併
template
import Parent from './Parent.vue'; export default { extends: Parent, beforeCreate() { this.$super.beforeCreate(); // 確保正確調用父組件的beforeCreate鉤子 this.$options.template = `<div>${this.$options.template}</div>`; // 在父組件模板外添加一個div }, // 其他選項... };
-
插槽(Slots)函數
在父組件中定義一個插槽函數,然後在子組件中覆蓋它。
父組件(Parent.vue):
<template> <div> <slot name="default" /> </div> </template>
子組件(Child.vue):
<template slot="default"> <div>這裏是覆蓋的內容</div> </template> <script> import Parent from './Parent.vue'; export default { extends: Parent, // 其他選項... }; </script>
總結:
通常情況下,使用extends
來修改template
並不是最佳實踐。extends
更適合用於複用非template
的選項,如data
、methods
、computed
等。如果你需要修改template
,考慮使用插槽(slots)或其他組合組件的方法。
請記住,直接修改template
可能會導致不可預見的問題,因爲父組件的template
可能依賴於特定的結構和指令。在使用上述方法時,請確保你充分理解父組件的template
結構,並在修改時保持謹慎。
直接修改繼承組件的template
可能會導致多種不可預見的問題,尤其是當父組件的template
依賴於特定的結構、樣式或行爲時。以下是一些可能出現的問題:
-
樣式問題: 父組件的樣式可能依賴於特定的HTML結構。如果你更改了
template
,可能會導致樣式失效或出現佈局問題,因爲CSS選擇器可能不再匹配新的元素結構。 -
功能問題: 如果父組件的邏輯依賴於特定的元素或組件,修改
template
可能會破壞這些依賴關係,導致功能不正常或完全失效。 -
數據綁定問題: 父組件可能使用了數據綁定或計算屬性,這些綁定可能依賴於特定的元素。更改
template
可能會導致數據綁定丟失或計算錯誤。 -
事件處理問題: 父組件可能定義了事件監聽器或事件委託。修改
template
可能會影響事件的觸發和處理,導致事件處理函數無法正確響應用戶交互。 -
插槽(Slots)問題: 如果你移除了或更改了父組件定義的插槽,可能會導致子組件無法正確渲染或傳遞數據給父組件。
-
組件通信問題: 如果父組件使用了
provide
/inject
、ref
或v-model
等通信機制,修改template
可能會破壞這些通信鏈路,導致數據流中斷。 -
性能問題: 重寫
template
可能會導致額外的DOM操作和重新渲染,影響應用的性能。 -
維護性問題: 直接修改
template
會使代碼難以維護和理解,尤其是在團隊協作環境中。這可能會導致代碼難以跟蹤和調試。
爲了避免這些問題,建議使用Vue提供的其他組合方式,如mixins
、components
、props
、events
和scoped slots
等,來擴展和自定義組件。這些方法提供了更清晰、更可控的方式來複用和修改組件的行爲,同時保持了組件的封裝性和可維護性。如果你確實需要修改template
,請確保充分理解父組件的工作原理,並在修改前進行徹底的測試。