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

基于Vue3實現(xiàn)組件封裝的技巧分享

 更新時間:2024年09月25日 11:02:41   作者:諸葛亮的芭蕉扇  
這篇文章主要介紹了基于Vue3實現(xiàn)組件封裝的技巧,本文在Vue3的基礎上針對一些常見UI組件庫組件進行二次封裝,旨在追求更好的個性化,更靈活的拓展,感興趣的小伙伴跟著小編一起來看看吧

需求

需求背景

日常開發(fā)中,我們經(jīng)常會使用一些UI組件庫諸如and design vue、element plus等輔助開發(fā),提升效率。有時我們需要進行個性化封裝,以滿 足在項目中大量使用的需求。

錯誤示范

基于a-modal封裝一個自定義Modal組件:修改modal樣式,按鈕樣式、每次關閉后銷毀、渲染到指定元素上等等,后續(xù)項目的彈窗全部基于該自定義組件。

<template>
    <div ref="myModal" class="custom-modal"></div>
    <a-modal
        v-model:visible="visible"
        centered
        destroyOnClose
        :getContainer="() => $refs.myModal"
        @ok="handleOk"
        @cancel="handleCancel"
        :style="{ width: '560px', ...style }"
        :cancelText="cancelText"
        :okText="okText"
    >
        <!-- 以上皆為該組件的默認屬性 -->
        <slot></slot>
    </a-modal>
</template>

<script setup>
const props = defineProps({
    title: {
        type: String,
        default: "",
    },
    style: {
        type: Object,
        default: () => ({}),
    },
    cancelText: {
        type: String,
        default: "取消",
    },
    okText: {
        type: String,
        default: "確定",
    },
});
const emits = defineEmits(["handleOk", "handleCancel"]);
const visible = ref(false);

const handleOk = () => {
    emits("handleOk");
};
const handleCancel = () => {
    emits("handleCancel");
};
defineExpose({ visible });
</script>

<style lang="less" scoped>
.custom-modal {
    :deep(.ant-modal) {
        //省略幾百行樣式代碼
    }
}
</style>

代碼封裝完成,于是乎我們便能在項目中應用帶有項目風格的彈窗

$attrs

問題來了:一切看起來都挺正常。直到有一天同事說:我想要去掉右上角的關閉按鈕,能改成自定義的嗎

簡單,直接加!

<!-- 省略不相關代碼 -->
<a-modal :closable="closable"></a-modal>
<script setup>
const props = defineProps({
    //...
    closable:{
        type: Boolean,
        default: false
    }
});
</script>

另一位同事說:我不想讓它是居中的,能改成自定義的嗎,還有一位同事說…

思考:這樣的情況多了,就有點難頂。每次一有新的需求,我就得改這個組件,導致這個組件代碼越來越冗余。那么是否有一種方式能夠?qū)鬟M來的屬性自動綁定給a-modal呢,有,那兒就是attrs

在這里插入圖片描述

注意:
1.vue提供了$attrs這么一個屬性用于接收父組件傳遞下來的屬性,$attrs不包括已經(jīng)寫入props的值
2.如果父組件傳遞了style,class,那么這這些值不僅會存在于$attrs,還會默認綁定至根元素上。這一點需要注意

<modalTest :footer="null" :centered="false" :zIndex="999" />
//此時的$attrs
{ "footer": null, "centered": false, "zIndex": 999 }

有了這個組件實例,結合v-bind我們就可以這么寫

<a-modal
    v-model:visible="visible"
    centered
    destroyOnClose
    :getContainer="() => $refs.myModal"
    :style="{ width: '560px', ...style }"
    v-bind="$attrs"
>
 <!-- 略  -->
</a-modal>

這樣一來,我們就可以使用a-modal提供的任意屬性和方法了

$slots

問題來了:插槽怎么辦,例如a-modal就提供了許多插槽,是不是要用哪個就先在自定義組件上寫好呢?

錯誤示例

<a-modal>
    <!-- default -->
    <slot></slot>

    <!-- title -->
    <template #title>
<slot name="title">{{ title }}</slot>
    </template>

    <!-- other -->
</a-modal>

弊端就像之前的,如果該原生提供了許多插槽,當有需要時豈不是頻繁去修改自定義組件添加相應的插槽,其實利用$slots可以解決這個問題

在這里插入圖片描述

官網(wǎng)的這段話簡明扼要的說出的插槽的原理,我們所傳遞的插槽最終都是變成

{
    'slotName':fn(...args)  //fn返回一個虛擬DOM
    'defautl': fn(...args) //默認插槽
}

也就是我們傳什么插槽進來,$slots就有什么值那么我們可以遍歷$slots中的值,有什么插槽我們便動態(tài)綁定什么插槽

<a-modal>
    <template v-for="(_val, name) in $slots" #[name]="options">
        <slot :name="name" v-bind="options || {}"> </slot>
    </template>
</a-modal>

#[name]="options",我們可以拿到原生a-modal在name這個插槽中傳遞來的一些狀態(tài)options,并綁定在<slot>上。詳情請查看官網(wǎng):作用域插槽。

這樣一來,我們原生a-modal怎么使用插槽,自定義組件就怎么使用插槽

<CustomModal>
    <template #title="{arg1, arg2}">
        content
    </template>
</CustomModal>

至此,封裝的代碼如下

<template>
    <div ref="myModal" class="custom-modal"></div>
    <a-modal
        v-model:visible="visible"
        centered
        :getContainer="() => $refs.myModal"
        :style="{ width: '560px'}"
        destroyOnClose
        v-bind="$attrs"
    >
        <template v-for="(_val, name) in $slots" #[name]="ops">
            <slot :name="name" v-bind="ops || {}"> </slot>
        </template>
    </a-modal>
</template>

<script setup>
const visible = ref(false);
defineExpose({ visible });
</script>

<style lang="less" scoped>
.custom-modal {
    //style
}
</style>

還有許多優(yōu)化的空間,例如當前父組件顯隱該Modal需使用ref的方式訪問visible。在vue3中也可以參考官網(wǎng)的做法這樣子寫

<template>
    <div ref="myModal" class="custom-modal"></div>
    <a-modal
        :visible="visible"
        //....
        v-bind="$attrs"
    >
          <!-- ...  -->
    </a-modal>
</template>

<script setup>
defineProps(['visible'])
const emit = defineEmits(); // 不用寫"update:visible",vue會自動加上
watch(
    () => props.visible,
    (newVal) => emit("update:visible", newVal);
);
</script>

那么使用這個控制這個組件的顯示隱藏就方便許多了

<CustomModal v-model:visible="visible"></CustomModal>

本文中的封裝方式是基于vue3來進行實現(xiàn),不局限在什么UI組件身上。如果使用的是vue2,情況稍有不同,請自行了解。

以上就是基于Vue3實現(xiàn)組件封裝的技巧分享的詳細內(nèi)容,更多關于Vue3組件封裝的資料請關注腳本之家其它相關文章!

相關文章

  • vue執(zhí)行配置選項npm?run?serve的本質(zhì)圖文詳解

    vue執(zhí)行配置選項npm?run?serve的本質(zhì)圖文詳解

    本地開發(fā)一般通過執(zhí)行npm run serve命令來啟動項目,那這行命令到底存在什么魔法?下面這篇文章主要給大家介紹了關于vue執(zhí)行配置選項npm?run?serve的本質(zhì)的相關資料,需要的朋友可以參考下
    2023-05-05
  • Vue中key為index和id的區(qū)別示例詳解

    Vue中key為index和id的區(qū)別示例詳解

    這篇文章主要介紹了Vue中key為index和id的區(qū)別詳解,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • vue項目中引入Sass實例方法

    vue項目中引入Sass實例方法

    在本文里小編給大家整理的是關于vue項目中引入Sass的相關知識點內(nèi)容,有需要的朋友們可以測試參考下。
    2019-08-08
  • 解決vue.js中settimeout遇到的問題(時間參數(shù)短效果不穩(wěn)定)

    解決vue.js中settimeout遇到的問題(時間參數(shù)短效果不穩(wěn)定)

    這篇文章主要介紹了解決vue.js中settimeout遇到的問題(時間參數(shù)短效果不穩(wěn)定),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • Vue3項目的3種創(chuàng)建方式代碼示例

    Vue3項目的3種創(chuàng)建方式代碼示例

    使用VUE3開發(fā)很久了,但一直沒進行總結和記錄,忙里偷閑整理搭建一套VUE3項目,正好記錄一下,這篇文章主要給大家介紹了關于Vue3項目的3種創(chuàng)建方式,需要的朋友可以參考下
    2024-03-03
  • vue遍歷中存在el-form之踩坑記錄

    vue遍歷中存在el-form之踩坑記錄

    這篇文章主要介紹了vue遍歷中存在el-form之踩坑記錄,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 在vue中使用inheritAttrs實現(xiàn)組件的擴展性介紹

    在vue中使用inheritAttrs實現(xiàn)組件的擴展性介紹

    這篇文章主要介紹了在vue中使用inheritAttrs實現(xiàn)組件的擴展性介紹,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 詳解vue中router-link標簽所必備了解的屬性

    詳解vue中router-link標簽所必備了解的屬性

    這篇文章主要介紹了vue中router-link標簽所必備了解的屬性,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • vue 支持百萬量級的無限滾動組件詳解

    vue 支持百萬量級的無限滾動組件詳解

    這篇文章主要為大家介紹了vue 支持百萬量級的無限滾動組件詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • Vue通過ref獲取不到$refs問題

    Vue通過ref獲取不到$refs問題

    這篇文章主要介紹了Vue通過ref獲取不到$refs問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01

最新評論

和静县| 榆树市| 鸡西市| 巫山县| 彭山县| 全南县| 建湖县| 武汉市| 凌海市| 昭通市| 奉新县| 东城区| 武鸣县| 巢湖市| 宜良县| 上思县| 乳源| 襄城县| 垣曲县| 邵阳县| 屯留县| 资阳市| 长治县| 夹江县| 栾城县| 平武县| 周宁县| 稻城县| 星座| 武隆县| 印江| 铜梁县| 康保县| 望江县| 高唐县| 岳阳县| 米脂县| 温泉县| 通化市| 响水县| 隆尧县|