vue extends繼承後修改template的解決方案

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的選項,如datamethodscomputed等。如果你需要修改template,考慮使用插槽(slots)或其他組合組件的方法。

  請記住,直接修改template可能會導致不可預見的問題,因爲父組件的template可能依賴於特定的結構和指令。在使用上述方法時,請確保你充分理解父組件的template結構,並在修改時保持謹慎。

  

直接修改繼承組件的template可能會導致多種不可預見的問題,尤其是當父組件的template依賴於特定的結構、樣式或行爲時。以下是一些可能出現的問題:

  1. 樣式問題: 父組件的樣式可能依賴於特定的HTML結構。如果你更改了template,可能會導致樣式失效或出現佈局問題,因爲CSS選擇器可能不再匹配新的元素結構。

  2. 功能問題: 如果父組件的邏輯依賴於特定的元素或組件,修改template可能會破壞這些依賴關係,導致功能不正常或完全失效。

  3. 數據綁定問題: 父組件可能使用了數據綁定或計算屬性,這些綁定可能依賴於特定的元素。更改template可能會導致數據綁定丟失或計算錯誤。

  4. 事件處理問題: 父組件可能定義了事件監聽器或事件委託。修改template可能會影響事件的觸發和處理,導致事件處理函數無法正確響應用戶交互。

  5. 插槽(Slots)問題: 如果你移除了或更改了父組件定義的插槽,可能會導致子組件無法正確渲染或傳遞數據給父組件。

  6. 組件通信問題: 如果父組件使用了provide/injectrefv-model等通信機制,修改template可能會破壞這些通信鏈路,導致數據流中斷。

  7. 性能問題: 重寫template可能會導致額外的DOM操作和重新渲染,影響應用的性能。

  8. 維護性問題: 直接修改template會使代碼難以維護和理解,尤其是在團隊協作環境中。這可能會導致代碼難以跟蹤和調試。

爲了避免這些問題,建議使用Vue提供的其他組合方式,如mixinscomponentspropseventsscoped slots等,來擴展和自定義組件。這些方法提供了更清晰、更可控的方式來複用和修改組件的行爲,同時保持了組件的封裝性和可維護性。如果你確實需要修改template,請確保充分理解父組件的工作原理,並在修改前進行徹底的測試。

  

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