最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺析vue3中組件的二次封裝

 更新時間:2023年09月15日 11:33:34   作者:拖孩  
在實際開發(fā)中每個開發(fā)者應(yīng)該都有經(jīng)歷過對組件進(jìn)行二次封裝,本文將從三個方面來基于 Element UI 的el-input組件簡單實現(xiàn)一下組件的二次封裝,有需要的可以參考下

背景

在實際開發(fā)中每個開發(fā)者應(yīng)該都有經(jīng)歷過對組件進(jìn)行二次封裝,在進(jìn)行封裝的時候需要保留組件已有的功能,這時需要重寫組件方法,當(dāng)組件已有大量功能時候,則需要重寫很多重復(fù)代碼。且組件功能進(jìn)行修改的時候,封裝的組件也需要對應(yīng)修改,從而造成許多開發(fā)和維護(hù)成本。下面將從三個方面來基于 Element UI 的el-input組件簡單實現(xiàn)一下組件的二次封裝。

第一方面:屬性綁定

在對組件封裝的時候首先會遇到就是綁定屬性了,簡單說就是將二次封裝的組件屬性綁定到el-input組件上。 可能有些小伙伴做的時候會將el-input的屬性全部寫到封裝組件 props 里面,然后再將這些屬性綁定到el-input組件上。這樣做不是不行,但是太雞肋了,而且浪費時間。那該如何做呢?

在 vue 實例中有一個屬性$attrs,這個屬性包含了組件所有透傳attributes的對象。是指由父組件傳入,且沒有被子組件聲明為 props 或是組件自定義事件的 attributes 和事件處理函數(shù)。 那我們就可以直接將$attrs以v-bind動態(tài)綁定到el-input組件上,就可以解決屬性綁定這方面的問題了。

<template>
  <el-input ref="refInput" v-bind="$attrs"></el-input>
</template>
<script>
export default {
}
</script>

第二方面:插槽

第二方面就是插槽的綁定了,可以和屬性綁定一樣,將所有的插槽全部寫出來,然后再一個一個寫到el-input組件上,如果插槽不多,也沒有什么影響,但是如果插槽很多呢,如果二次封裝的是有可能會修改的組件呢?那這個二次封裝的組件也要同步修改,很麻煩!那又該如何做呢?

我們可以通過另一個屬性$slots,這個屬性表示父組件所傳入插槽的對象。每一個插槽都在$slots上暴露為一個函數(shù),返回一個 vnode 數(shù)組,同時 key 名對應(yīng)著插槽名。 那我們就可以遍歷$slots動態(tài)綁定到el-input組件上,就可以解決綁定插槽這方面的問題了。

<template>
  <el-input ref="refInput" v-bind="$attrs">
    <template v-for="(value, name) in $slots" #[name]>
      <slot :name="name" />
    </template>
  </el-input>
</template>
<script>
export default {
}
</script>

但如果再考慮得深一點,你會發(fā)現(xiàn)有的時候這個組件會向這個插槽傳遞一些數(shù)據(jù),就是作用域插槽了。

<template>
  <el-input ref="refInput" v-bind="$attrs">
    <template v-for="(_value, name) in $slots" #[name]="slotData">
      <slot :name="name" v-bind="slotData || {}" />
    </template>
  </el-input>
</template>
<script>
export default {
}
</script>

第三方面: ref

我們使用組件的時候保不齊就會使用ref調(diào)用組件里面暴露的方法。我們可以通過這么幾種方式實現(xiàn):

  • 暴露el-input的ref,然后通過this.$ref[二次封裝組件的ref][el-input的ref].focus()的方式調(diào)用。
  • 在組件內(nèi)重新寫el-input的方法并綁定到el-input組件上,然后暴露出去。

以上這兩種方式都可以是現(xiàn)實,但是我們實際開發(fā)過程中如果組件被修改了,那所有使用該組件的地方都需要進(jìn)行調(diào)整,而且咱們都不希望寫這么多無聊的代碼。就出現(xiàn)了以下主要介紹方式:

我們換一種思路,我們要做的無非就是將el-input的方法提取到我們封裝的組件上暴露給使用組件的地方使用。那我們就可以將el-input的方法通過ref的方式獲取到然后放到封裝組件的實例里面去。

在進(jìn)行組合式API封裝前先介紹一個屬性expose,用于聲明當(dāng)組件實例被父組件通過模板引用訪問時暴露的公共屬性。默認(rèn)情況下,當(dāng)通過 $parent$root 或模板引用訪問時,組件實例將向父組件暴露所有的實例屬性。

選項式

<template>
  <el-input ref="refInput" v-bind="$attrs">
    <template v-for="(_value, name) in $slots" #[name]="slotData">
      <slot :name="name" v-bind="slotData || {}" />
    </template>
  </el-input>
</template>
<script>
export default {
  data() {
    return {}
  },
  mounted() {
    const entries = Object.entries(this.$refs.refInput)
    for(const [key, value] of entries) {
      this[key] = value
    }
  }
}
</script>

組合式

在組合式setup函數(shù)中我們需要先通過getCurrentInstance方法獲取當(dāng)前組件實例,然后將提取el-input組件暴露的方法暴露出去。需要注意的是我們在使用setup方法的時候會在最后將需要使用到的屬性或者方法return出去使用。但是在setup函數(shù)它在beforeCreate之前發(fā)生,所以我們獲取不到el-input組件的實例,所以就需要在onMounted的時候?qū)?code>el-input組件暴露的方法加到當(dāng)前組件實例的expose屬性中,但是沒有主動聲明暴露的時候expose屬性是null,所以我們需要先主動聲明暴露,在onMounted的時候?qū)?code>el-input組件暴露的方法添加到expose中。

<template>
  <el-input ref="refInput" v-bind="$attrs">
    <template v-for="(_value, name) in $slots" #[name]="slotData">
      <slot :name="name" v-bind="slotData || {}" />
    </template>
  </el-input>
</template>
<script>
import { ref, onMounted, getCurrentInstance }  from 'vue'
export default {
  setup(props, context) {
    const instance = getCurrentInstance()
    const refInput = ref()
    onMounted(() => {
      const entries = Object.entries(refInput.value.$.exposed)
      for (const [key, value] of entries) {
        instance.exposed[key] = value
      }
    })
    context.expose()
    return {
      refInput
    }
  }
}
</script>

setup標(biāo)簽

setup標(biāo)簽寫法與組合式封裝方法相似。不同的是在setup標(biāo)簽中當(dāng)前組件實例的expose不為null,所以不需要主動聲明暴露。

<template>
  <el-input ref="refInput" v-bind="$attrs">
    <template v-for="(_value, name) in $slots" #[name]="slotData">
      <slot :name="name" v-bind="slotData || {}" />
    </template>
  </el-input>
</template>
<script setup>
import { ref, onMounted, getCurrentInstance }  from 'vue'
const instance = getCurrentInstance()
const refInput = ref()
onMounted(() => {
  const entries = Object.entries(refInput.value.$.exposed)
  for (const [key, value] of entries) {
    instance.exposed[key] = value
  }
})
</script>

附上源碼

到此這篇關(guān)于淺析vue3中組件的二次封裝的文章就介紹到這了,更多相關(guān)vue3組件封裝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 創(chuàng)建項目及包管理yarn create vite源碼學(xué)習(xí)

    創(chuàng)建項目及包管理yarn create vite源碼學(xué)習(xí)

    這篇文章主要為大家介紹了創(chuàng)建項目及包管理yarn create vite源碼學(xué)習(xí)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • Vue實現(xiàn)模糊查詢搜索功能的步驟詳解

    Vue實現(xiàn)模糊查詢搜索功能的步驟詳解

    本文主要介紹了Vue實現(xiàn)模糊查詢搜索功能的步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-10-10
  • vue中el-tree增加節(jié)點后如何重新刷新

    vue中el-tree增加節(jié)點后如何重新刷新

    這篇文章主要介紹了vue中el-tree增加節(jié)點后如何重新刷新,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • vue項目中銷毀window.addEventListener事件監(jiān)聽解析

    vue項目中銷毀window.addEventListener事件監(jiān)聽解析

    這篇文章主要介紹了vue項目中銷毀window.addEventListener事件監(jiān)聽,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • 詳解vuex之store源碼簡單解析

    詳解vuex之store源碼簡單解析

    這篇文章主要介紹了詳解vuex之store源碼簡單解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • vue-cli腳手架打包靜態(tài)資源請求出錯的原因與解決

    vue-cli腳手架打包靜態(tài)資源請求出錯的原因與解決

    這篇文章主要給大家介紹了關(guān)于vue-cli腳手架打包靜態(tài)資源請求出錯的原因與解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用vue-cli具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Vue預(yù)渲染:prerender-spa-plugin生成靜態(tài)HTML與vue-meta-info更新meta

    Vue預(yù)渲染:prerender-spa-plugin生成靜態(tài)HTML與vue-meta-info更新meta

    Vue.js中,prerender-spa-plugin和vue-meta-info插件的結(jié)合使用,提供了解決SEO問題的方案,prerender-spa-plugin通過預(yù)渲染技術(shù)生成靜態(tài)HTML,而vue-meta-info則能動態(tài)管理頁面元數(shù)據(jù),本文將探討如何使用這兩個工具優(yōu)化Vue.js項目的SEO表現(xiàn),包括安裝、配置及注意事項
    2024-10-10
  • Vue:Bin Code Editor格式化JSON編輯器詳解

    Vue:Bin Code Editor格式化JSON編輯器詳解

    文章介紹了BinCodeEditor組件的安裝、注冊、使用方法以及注意事項,組件可以通過npm或yarn安裝,支持全局或局部注冊,使用時,可以通過value屬性綁定JavaScript值,或使用v-model,組件事件與方法包括編輯區(qū)顯示問題的解決
    2024-12-12
  • 詳解vue配置請求多個服務(wù)端解決方案

    詳解vue配置請求多個服務(wù)端解決方案

    這篇文章主要介紹了詳解vue配置請求多個服務(wù)端解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • vue.js實現(xiàn)簡單計時器功能

    vue.js實現(xiàn)簡單計時器功能

    這篇文章主要為大家詳細(xì)介紹了vue.js實現(xiàn)簡單計時器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08

最新評論

高碑店市| 大厂| 邯郸市| 定边县| 广灵县| 陆良县| 汶上县| 龙门县| 新化县| 百色市| 晋中市| 三门峡市| 锡林浩特市| 石河子市| 历史| 广汉市| 合川市| 年辖:市辖区| 莱芜市| 林州市| 探索| 瓮安县| 灵武市| 丽水市| 恩平市| 兴仁县| 莆田市| 内黄县| 台前县| 长乐市| 望江县| 梨树县| 天镇县| 洛南县| 遵义县| 昭觉县| 全椒县| 鸡泽县| 新乐市| 林芝县| 岱山县|