前言
最近在使用element-ui框架,用到了Dialog對話方塊元件,大致實現的效果,跟我之前自己在移動端專案裡面弄的一個彈窗元件差不太多。然後就想著把這種彈窗元件的實現方式與大家分享一下,下面本文會帶著大家手摸手實現一個彈窗元件。
本文主要內容會涉及到彈窗遮罩的實現,slot
插槽的使用方式,props
、$emit
傳參,具體元件程式碼也傳上去了。如果喜歡的話可以點波贊/關注,支援一下,希望大家看完本文可以有所收穫。
個人部落格瞭解一下:obkoro1.com
元件最後實現的效果
實現步驟
- 先搭建元件的html和css樣式,遮罩層和內容層。
- 定製彈窗內容:彈窗元件通過
slot
插槽接受從父元件那裡傳過來彈窗內容。 - 定製彈窗樣式:彈窗元件通過
props
接收從父元件傳過來的彈窗寬度,上下左右的位置。 - 元件開關:通過父元件傳進來的
props
控制元件的顯示與隱藏,子元件關閉時通過事件$emit
觸發父元件改變值。
1.搭建元件的html和css樣式。
html結構:一層遮罩層,一層內容層,內容層裡面又有一個頭部title和主體內容和一個關閉按鈕。
下面是元件中的html結構,裡面有一些後面才要加進去的東西,如果看不懂的話可以先跳過,
<template>
<div class="dialog">
<!--外層的遮罩 點選事件用來關閉彈窗,isShow控制彈窗顯示 隱藏的props-->
<div class="dialog-cover back" v-if="isShow" @click="closeMyself"></div>
<!-- transition 這裡可以加一些簡單的動畫效果 -->
<transition name="drop">
<!--style 通過props 控制內容的樣式 -->
<div class="dialog-content" :style="{top:topDistance+'%',width:widNum+'%',left:leftSite+'%'}" v-if="isShow">
<div class="dialog_head back">
<!--彈窗頭部 title-->
<slot name="header">提示資訊</slot>
</div>
<div class="dialog_main" :style="{paddingTop:pdt+'px',paddingBottom:pdb+'px'}">
<!--彈窗的內容-->
<slot name="main">彈窗內容</slot>
</div>
<!--彈窗關閉按鈕-->
<div class="foot_close" @click="closeMyself">
<div class="close_img back"></div>
</div>
</div>
</transition>
</div>
</template>
複製程式碼
下面是元件中的主要的css樣式,裡面都做了充分的註釋,主要通過z-index
和background
達到遮罩的效果,具體內容的css可以根據自己的需求來設定。
<style lang="scss" scoped>
// 最外層 設定position定位
.dialog {
position: relative;
color: #2e2c2d;
font-size: 16px;
}
// 遮罩 設定背景層,z-index值要足夠大確保能覆蓋,高度 寬度設定滿 做到全屏遮罩
.dialog-cover {
background: rgba(0,0,0, 0.8);
position: fixed;
z-index: 200;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
// 內容層 z-index要比遮罩大,否則會被遮蓋,
.dialog-content{
position: fixed;
top: 35%;
// 移動端使用felx佈局
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 300;
}
</style>
複製程式碼
2. 通過slot
定製彈窗內容
這一步,只要理解了slot
的作用以及用法,就沒有問題了。
單個插槽:
<slot>這是在沒有slot傳進來的時候,才顯示的彈窗內容</slot>
複製程式碼
上面是單個插槽也叫預設插槽,在父元件中使用插槽的正確姿勢:
<my-component>
<!--在my-component裡面的所有內容片段都將插入到slot所在的DOM位置,並且會替換掉slot標籤-->
<!--這兩個p標籤,將替換整個slot標籤裡面的內容-->
<p>這是一些初始內容</p>
<p>這是更多的初始內容</p>
</my-component>
複製程式碼
ps:如果子元件裡面包含slot
插槽,那麼上面的p標籤的內容將會被丟棄。
具名插槽:
所謂的具名插槽,即為slot
標籤賦一個name
屬性,具名插槽可以父元件中不同的內容片段放到子元件的不同地方,具名插槽還是可以擁有一個預設插槽。下面可以看一下彈窗元件插槽的使用方式:
<div class="dialog_head back ">
<!--彈窗頭部 title-->
<slot name="header">提示資訊</slot>
</div>
<div class="dialog_main " :style="{paddingTop:pdt+'px',paddingBottom:pdb+'px'}">
<!--彈窗的內容-->
<slot name="main">彈窗內容</slot>
</div>
複製程式碼
在父元件中的使用方式:
-
將彈窗元件引入要使用的元件中,並通過
components
註冊成為元件。 -
父元件中彈窗元件插槽的使用方法如下。
<dialogComponent> <div slot="header">插入到name為header的slot標籤裡面</div> <div class="dialog_publish_main" slot="main"> 這裡是內容插入到子元件的slot的name為main裡面,可以在父元件中新增class定義樣式,事件型別等各種操作 </div> </dialogComponent> 複製程式碼
關於元件中用到的插槽的介紹就到這裡了,插槽在彈窗元件中的應用是一個典型的栗子,可以看到插槽作用相當強大,而插槽本身的使用並不難,同學們愛上插槽了沒有?
3.通過props
控制彈窗顯隱&&定製彈窗style
psops
是Vue中父元件向子元件傳遞資料的一種方式,不熟悉的小夥伴們可以看一下props文件。
因為彈窗元件都是引到別的元件裡面去用的,為了適合不同元件場景中的彈窗,所以彈窗元件必須具備一定的可定製性,否則這樣的元件將毫無意義,下面介紹一下props的使用方式,以彈窗元件為例:
-
首先需要在被傳入的元件中定義props的一些特性,驗證之類的。
-
然後在父元件中繫結props資料。
<script> export default { props: { isShow: { //彈窗元件是否顯示 預設不顯示 type: Boolean, default: false, required:true, //必須 }, //下面這些屬性會繫結到div上面 詳情參照上面的html結構 // 如: :style="{top:topDistance+'%',width:widNum+'%'}" widNum:{ //內容寬度 type: Number, default:86.5 }, leftSite:{ // 左定位 type: Number, default:6.5 }, topDistance: { //top上邊距 type: Number, default:35 }, pdt:{ //上padding type: Number, default:22 }, pdb:{ //下padding type: Number, default:47 } }, } </script> 複製程式碼
父元件中使用方式:
<dialogComponent :is-show="status.isShowPublish" :top-distance="status.topNum">
</dialogComponent>
複製程式碼
ps:props傳遞資料不是雙向繫結的,而是單向資料流,父元件的資料變化時,也會傳遞到子元件中,這就意外著我們不應該在子元件中修改props。所以我們在關閉彈窗的時候就需要通過$emit
來修改父元件的資料,然後資料會自動傳到子元件中。
現在基本上彈窗元件都已實現的差不多了,還差一個彈窗的關閉事件,這裡就涉及到子元件往父元件傳參了。
4.$emit
觸發父元件事件修改資料,關閉彈窗
Vue中在子元件往父元件傳參,很多都是通過$emit
來觸發父元件的事件來修改資料。
在子元件中,在點選關閉,或者遮罩層的時候觸發下面這個方法:
methods: {
closeMyself() {
this.$emit("on-close");
//如果需要傳參的話,可以在"on-close"後面再加引數,然後在父元件的函式裡接收就可以了。
}
}
複製程式碼
父元件中的寫法:
<dialogComponent :is-show="status.isShowPublish" :top-distance="status.topNum" @on-close="closeDialog">
</dialogComponent>
//"on-close是監聽子元件的時間有沒有觸發,觸發的時候執行closeDialog函式
methods:{
closeDialog(){
// this.status.isShowPublish=false;
//把繫結的彈窗陣列 設為false即可關閉彈窗
},
}
複製程式碼
可以用彈窗元件實現下列這種資訊展示,或者事件互動:
彈窗元件程式碼
上面是把彈窗的每個步驟拆分開來,一步步解析的,每一步都說的比較清楚了,具體連起來的話,可以看看程式碼,再結合文章就能理的很清楚了。
小結:
這個彈窗元件,實現起來一點都不難,我這裡主要是提供了一個實現方式,當專案中有需要的話,大家也可以自己擼一個出來,以上就是本文的內容了,希望同學們看完能有所收穫。
希望看完的朋友可以點個喜歡/關注,您的支援是對我最大的鼓勵。
最後:如需轉載,請放上原文連結並署名。碼字不易,感謝支援!本人寫文章本著交流記錄的心態,寫的不好之處,不撕逼,但是歡迎指點。
以上2018.4.21