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

Vue3實(shí)現(xiàn)組件二次封裝的小技巧分享

 更新時(shí)間:2024年09月12日 09:01:21   作者:唐詩(shī)  
組件的二次封裝:保留組件已有的功能,需要重寫組件方法,當(dāng)組件已有大量功能時(shí)候,則需要重寫很多重復(fù)代碼,且組件功能進(jìn)行修改的時(shí)候,封裝的組件也需要對(duì)應(yīng)修改,從而造成許多開發(fā)和維護(hù)成本,本文給大家分享了Vue3實(shí)現(xiàn)組件二次封裝的小技巧,需要的朋友可以參考下

雙向數(shù)據(jù)綁定

我們以 input 組件作為例子

雙向數(shù)據(jù)綁定的原理及實(shí)現(xiàn)想必大家已經(jīng)爛熟于心了直接看官網(wǎng)吧!

子組件接受一個(gè) modelValue 的 prop, 通過 emit 觸發(fā) update:modelValue 事件完成數(shù)據(jù)的更新

父組件直接 v-model="xxxx"

嫌麻煩官方還提供了 defineModel() 用于簡(jiǎn)化上邊的步驟

向子組件傳遞插槽

我們以 input 組件作為例子,創(chuàng)建一個(gè) WrapInput.vue 組件

未學(xué)習(xí)之前

WrapInput.vue 常規(guī)的做法,遍歷 $slots 來(lái)實(shí)現(xiàn)

<script setup lang="ts">
const model = defineModel()

</script>

<template>
  <el-input v-model="model" placeholder="Please input" >
    <template v-for="(_, slot) in $slots" :key="solt" v-slot:[slot]="slotProps">
      <slot :name="slot" v-bind="slotProps"></slot>
    </template>
  </el-input>
</template>

<style lang='scss' scoped></style>

在 app.vue 中引入并傳遞 prepend、append 插槽

<script setup lang="ts">
import { ref } from "vue";
import WrapInput from "./components/WrapInput.vue";

const inputText = ref('')
</script>

<template>
  <WrapInput v-model="inputText">
    <template #prepend>Http://</template>
    <template #append>.com</template>
  </WrapInput>

  <div>
    {{inputText}}
  </div>
</template>

<style scoped>
</style>

正確渲染了插槽

學(xué)習(xí)之后

讓我們來(lái)修改下 WrapInput.vue

<script setup lang="ts">
import { h } from "vue";
import { ElInput } from "element-plus";
const model = defineModel()
</script>

<template>
<component :is="h(ElInput, $attrs, $slots)" v-model="model"></component>
</template>

<style lang='scss' scoped></style>

app.vue 的代碼不做任何修改

插槽正常傳遞、數(shù)據(jù)更新正常,看到這種寫法的時(shí)候有點(diǎn)震驚的

component 組件為什么可以傳入 h 函數(shù)

看下 h 函數(shù)的文檔, h(ElInput, $attrs, $slots) 是創(chuàng)建了一個(gè)虛擬 dom 節(jié)點(diǎn)

而 component 組件的 is 屬性則可以接收

  • 被注冊(cè)的組件名
  • 導(dǎo)入的組件對(duì)象
  • 一個(gè)返回上述值之一的函數(shù)

當(dāng) component 組件的 is 屬性接收到一個(gè)函數(shù)時(shí),Vue 會(huì)調(diào)用這個(gè)函數(shù)并使用其返回值作為要渲染的組件。

在這種情況下,h(ElInput, $attrs, $slots) 會(huì)立即執(zhí)行并返回一個(gè) VNode,這個(gè) VNode 描述了如何渲染 ElInput 組件。

獲取子組件的 ref

未學(xué)習(xí)之前

之前的自己的寫法有點(diǎn)蠢的具體的做法是在子組件創(chuàng)建一個(gè) getRef 的函數(shù)把 ref 暴露出去,父組件調(diào)用 getRef 方法后在執(zhí)行子組件方法的調(diào)用,大概是下邊這樣

WrapInput1.vue

<script setup lang="ts">
import { h, ref} from "vue";
import { ElInput } from "element-plus";
const model = defineModel()

const inputRef = ref()

function getRef () {
  return inputRef.value
}

defineExpose({
  getRef
})
</script>

<template>
  <component ref="inputRef" :is="h(ElInput, $attrs, $slots)" v-model="model"></component>
</template>

<style lang='scss' scoped></style>

學(xué)習(xí)之后

WrapInput.vue

<script setup lang="ts">
import { h, ref } from "vue";
import { ElInput } from "element-plus";
const model = defineModel()

const inputRef = ref()

defineExpose(new Proxy({}, {
  get(_target, prop)  {
    return inputRef.value?.[prop]
  },
  has (_target, prop) {
    return prop in inputRef.value
  }
}))

</script>

<template>
  <component :is="h(ElInput, $attrs, $slots)" v-model="model" ref="inputRef"></component>
</template>

<style lang='scss' scoped></style>

使用 Proxy 代理暴露出去的方法,是有點(diǎn)震驚的,還能這么寫

App.vue

<script setup lang="ts">
import { ref } from "vue";
import WrapInput from "./components/WrapInput.vue";

const inputText = ref('')

const prependSlotText =  ref('Http://')
const appendSlotText =  ref('.com')

function updateSlotInfo (){
  prependSlotText.value = 'https://'
  appendSlotText.value = `${new Date().getTime()}`
}

const wrapInputRef = ref()
function setWrapInputFocus () {
  wrapInputRef.value?.focus()
}
</script>

<template>
  <WrapInput v-model="inputText" ref="wrapInputRef">
    <template #prepend>{{ prependSlotText }}</template>
    <template #append>{{ appendSlotText }}</template>
  </WrapInput>

  <div style="margin: 20px 0;">
    {{inputText}}
  </div>

  <el-button type="primary" @click="updateSlotInfo">更新插槽內(nèi)容</el-button>
  <el-button type="primary" @click="setWrapInputFocus">set input focus</el-button>
  
</template>

<style scoped>
</style>

調(diào)用組件的 focus 方法讓 WrapInput.vue 組件獲取焦點(diǎn)

總結(jié)

本文實(shí)踐了在 vue3 中在二次封裝組件時(shí)如何實(shí)現(xiàn) v-model、插槽傳遞、子組件 ref 獲取

插槽傳遞通過向 component 組件的 is 屬性傳遞 h 函數(shù)創(chuàng)建虛擬 dom 來(lái)實(shí)現(xiàn)

獲取子組件的 ref 則是使用 new Proxy 的方式來(lái)實(shí)現(xiàn)

以上就是Vue3實(shí)現(xiàn)組件二次封裝的小技巧分享的詳細(xì)內(nèi)容,更多關(guān)于Vue3組件二次封裝的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vxe-table vue 表格禁用單元格編輯的兩種實(shí)現(xiàn)方式

    vxe-table vue 表格禁用單元格編輯的兩種實(shí)現(xiàn)方式

    本文介紹vxe-table禁用單元格編輯的兩種方式,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2025-06-06
  • 深入理解Vue3 computed

    深入理解Vue3 computed

    本文主要介紹了Vue3 computed的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-08-08
  • Vue中消息橫向滾動(dòng)時(shí)setInterval清不掉的問題及解決方法

    Vue中消息橫向滾動(dòng)時(shí)setInterval清不掉的問題及解決方法

    最近在做項(xiàng)目時(shí),需要進(jìn)行兩個(gè)組件聯(lián)動(dòng),一個(gè)輪詢獲取到消息,然后將其傳遞給另外一個(gè)組件進(jìn)行橫向滾動(dòng)展示,結(jié)果滾動(dòng)的速度越來(lái)越快。接下來(lái)通過本文給大家分享Vue中消息橫向滾動(dòng)時(shí)setInterval清不掉的問題及解決方法,感興趣的朋友一起看看吧
    2019-08-08
  • vue之ele多級(jí)聯(lián)組件的使用方法詳解

    vue之ele多級(jí)聯(lián)組件的使用方法詳解

    這篇文章為大家詳細(xì)主要介紹了vue之ele多級(jí)聯(lián)組件的使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • 如何基于uniapp開發(fā)android播放webrtc流詳解

    如何基于uniapp開發(fā)android播放webrtc流詳解

    這篇文章主要介紹了在uniapp中播放RTSP和WebRTC協(xié)議流的區(qū)別,以及如何封裝WebrtcVideo組件和音視頻實(shí)時(shí)通訊的實(shí)現(xiàn),文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-02-02
  • Vue3?封裝擴(kuò)展并簡(jiǎn)化Vuex在組件中的調(diào)用問題

    Vue3?封裝擴(kuò)展并簡(jiǎn)化Vuex在組件中的調(diào)用問題

    這篇文章主要介紹了Vue3?封裝擴(kuò)展并簡(jiǎn)化Vuex在組件中的調(diào)用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-01-01
  • 詳解elementui之el-image-viewer(圖片查看器)

    詳解elementui之el-image-viewer(圖片查看器)

    這篇文章主要介紹了詳解elementui之el-image-viewer(圖片查看器),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Vue切換Tab動(dòng)態(tài)渲染組件的操作

    Vue切換Tab動(dòng)態(tài)渲染組件的操作

    這篇文章主要介紹了Vue切換Tab動(dòng)態(tài)渲染組件的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2020-09-09
  • 用Vue寫一個(gè)分頁(yè)器的示例代碼

    用Vue寫一個(gè)分頁(yè)器的示例代碼

    本篇文章主要介紹了用Vue寫一個(gè)分頁(yè)器的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧
    2018-04-04
  • vue 實(shí)現(xiàn)dot-dropdown的實(shí)例代碼

    vue 實(shí)現(xiàn)dot-dropdown的實(shí)例代碼

    這篇文章主要介紹了vue實(shí)現(xiàn)dot-dropdown的相關(guān)操作,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2025-06-06

最新評(píng)論

乐业县| 曲周县| 喀喇| 犍为县| 改则县| 西贡区| 上高县| 汪清县| 内黄县| 惠来县| 高台县| 太和县| 东阿县| 沂源县| 建昌县| 广西| 台山市| 晋宁县| 布拖县| 晴隆县| 寿光市| 合江县| 安康市| 大埔区| 社会| 定日县| 长治县| 晋城| 林州市| 莱西市| 青海省| 鹤壁市| 竹山县| 敦化市| 蓝山县| 磴口县| 康乐县| 连平县| 唐海县| 临猗县| 随州市|