??Hi~ 大家好,我是小鑫同學,一位長期從事前端開發的編程愛好者,我將使用更為實用的案例輸出更多的編程知識,同時我信奉分享是成長的唯一捷徑,在這里也希望我的每一篇文章都能成為你技術落地的參考~
??技術&代碼分享
- 我在 IT200 總結技術學習;
- 我在 1024Code 在線撰寫代碼;
- 我在 掘金 分享技術文章;
- 我在 Github 參與開源學習;
??推薦幾個好用的工具
- var-conv 適用于VSCode IDE的代碼變數名稱快速轉換工具
- generator-vite-plugin 快速生成Vite插件模板專案
- generator-babel-plugin 快速生成Babel插件模板專案
進入正題
在各種場景的開發中Dialog組件的出現頻率都是非常高的,Dialog組件作為一個容器組件受容器內業務代碼復雜度的影響,代碼行數、變數及函式的定義可能會很多,這樣的組件就一定要考慮封裝使用,以保證主流程代碼的簡潔,下面一起來看一下如何利用面向物件的思想來封裝它吧~
技術選型
Vuejs3.x + Typescript + <script setup> 是目前撰寫SFC組件的推薦方式,相比直接使用setup函式編碼體驗會更好,AntdV組件庫的使用頻率相比ElementUI要高,推薦新專案直接選用AntdV,完整代碼可以在1024Code直接Fork或匯出到本地,
代碼分析
下面的代碼來自AntdV組件庫Model組件的示例,Model需要一個visible屬性來控制是否顯示和隱藏,由button的click事件來觸發修改visible屬性顯示,并且可以通過ok事件的觸發來表示對Model內業務邏輯的認可,
從這個示例來看代碼當然是沒有拆分組件的必要的,當但代表主流程業務的button和由modal包裹的業務流程變得多起來的時候,script里面的代碼可讀性將大大降低,
<script setup lang="ts">
import { ref } from 'vue';
const visible = ref<boolean>(false);
const showModal = () => {
visible.value = https://www.cnblogs.com/it200/archive/2023/03/08/true;
};
const handleOk = (e: MouseEvent) => {
console.log(e);
visible.value = false;
};
</script>
普通的組件拆分
常規的組件拆分大家按習慣來做一定是考慮通過Props傳遞visible引數來控制子組件中Model組件的顯示,但是你是沒有辦法直接將Props的visible屬性系結到Model,因為在關閉彈窗是涉及到了修改變數,這樣的做法在Vuejs中認為是危險的(父子組件單向資料流),所以必須要通過子組件重新定義變數來接收后使用;
另一個問題就是父組件在給子組件傳visible引數時在父組件也有屬性定義,這個屬性在改為true后同樣因單向資料流的限制是無法在Model關閉時動態變更為false,這樣的Model就只能被打開一次,合理的解決范式就是通過emit在Model關閉時通知(回呼)父組件,由父組件主動修改它定義的變數,
這樣拆分組件不僅定義了多份控制顯示/隱藏的變數,并且還需要在回呼中專門處理,這給組件的開發和使用都造成了一定的麻煩,所以我不推薦這種拆分方式,
面向物件拆分組件
面向物件的第一大概念就是封裝,所以只要涉及封裝就完全可以用面向物件的思想來做,在案例中控制顯示隱藏的visible屬性和ok事件都是屬于這個組件物件自己的,只能定義在子組件中,操作Model顯示隱藏的方式不能通過Props傳遞,同樣需要由組件物件自己提供,在使用了<script setup>后,組件默認為關閉狀態,需要使用defineExpose函式將需要暴露的函式暴露給父組件使用,前面提到的emit在這里還是比不可少了,但是僅僅是作為將業務處理的結果傳遞給父組件,
<script setup lang="ts">
import { ref, defineExpose, defineEmits } from 'vue'
const visible = ref<boolean>(false);
const open = () => visible.value = https://www.cnblogs.com/it200/archive/2023/03/08/true;
const close = () => visible.value = false;
defineExpose({
open,
})
const emit = defineEmits<{
(e:'complete', code: number): void
}>()
const handleOk = (_) => {
close();
emit('complete', 200);
};
</script>
<template>
<a-modal v-model:visible="visible" title="Basic Modal" @ok="handleOk">
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</a-modal>
</template>
<style scoped>
</style>
面向物件使用組件
在面向物件封裝時并不需要過多的考慮顯示隱藏狀態變化的傳遞,屬于組件本身的屬性、函式有組件自己控制包括是否對外暴露等,那么在使用的時候也是非常簡潔的,在父組件中只關注Model什么時候需要打開和關閉后回呼的資料處理即可,
<script setup lang="ts">
import { ref } from 'vue';
import BusinessDialog from './components/BusinessDialog.vue';
const businessDialogRef = ref<InstanceType<typeof BusinessDialog>>();
const showModal = () => {
businessDialogRef.value?.open();
}
const onComplete = (e: any) => {
console.log(e);
}
</script>
<template>
<a-button type="primary" @click="showModal">Open Modal</a-button>
<BusinessDialog ref="businessDialogRef" @complete="onComplete" />
</template>
<style scoped>
</style>
總結
文中介紹的關于DialogComponent組件的封裝思想是我所推薦的,因為它不僅開發子組件是不需要過多外部的干擾,在使用子組件是也不需要過多的考慮,這也是封裝的意義所在,在其中使用到了defineExpose()、defineEmits(),對于很少使用<script setup>方式的小伙伴也是不熟悉的,可以通過Vuejs檔案學習,最后在父組件定義子組件的ref時使用的InstanceType屬于Typescript中的型別編程,感興趣的也可以了解一下,好了,今天就說這么多,下次見~
PS:完整代碼見1024Code;
如果看完覺得有識訓,歡迎點贊、評論、分享支持一下,你的支持和肯定,是我堅持寫作的動力~
本文來自博客園,作者:FE小鑫同學,轉載請注明原文鏈接:https://www.cnblogs.com/it200/p/17190915.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/546239.html
標籤:其他
上一篇:前端設計模式——觀察者模式
下一篇:前端設計模式——發布訂閱模式
