這篇文章給大家分享的是有關(guān)怎樣給element添加一個抽屜組件的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
為同江等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及同江網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、同江網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!
一、實(shí)踐
1.分析
一個抽屜組件的z-index必定是在當(dāng)前頁面之上的,在抽屜主體之外的區(qū)域還會有一層半透明的遮罩層,知道這些就很容易了
// drawer.vue <template> <div class="mask"></div> <div class="drawer"> <div class="drawer_body"></div> </div> </template> <style scoped> .drawer { position: absolute; height: 100vh; top: 0; bottom: 0; right: 0; left: 0; z-index: 1000000 !important; } .drawer .drawer_body { height: 100%; position: absolute; z-index: 1000001; background-color: #fff; } .mask { height: 100vh; width: 100vw; position: absolute; z-index: 1000000; top: 0; left: 0; background-color: #000; opacity: 0.5; } </style>
現(xiàn)在已經(jīng)是我們想要的樣子了,接下來是給drawer_body添加樣式
作為一個靈活的組件庫,我們希望樣式是可以隨時定制的,所以,接下要添加的樣式都 使用props
動態(tài)綁定的
參考iview的樣式,除了抽屜的寬度,還需要設(shè)置抽屜的方向,當(dāng)我們需要抽屜時讓它顯示出來,不需要時隱藏它,或者為了更加顯眼,甚至給抽屜更換背景色......,這些都是可以實(shí)現(xiàn)的,看下面的代碼
<script> export default { props: { // 是否顯示drawer drawerVisible: Boolean, // drawer方向 direction: { type: String, validator(val) { return ["right", "left"].indexOf(val) !== -1; } }, // drawer寬度 width: { type: Number, default: 400 }, // drawer背景色 background: { type: String, default: "#ffffff" }, // 是否顯示遮罩層 mask: { type: Boolean, default: true } } }; </script>
對于寬度和背景色,你還需要額外的處理下
<div class="drawer_body" :style="{'right':direction=='right'?'0':'auto', 'left':direction=='left'?'0':'auto', 'width':width+'px','background':background}" >drawer</div>
你只需在使用的地方引入組件,然后提供你想修改的props值
//index.vue <template> <div> ... <el-button size="mini" @click="visible">顯示抽屜</el-button> <Drawer :drawerVisible="drawerVisible" direction="right" :mask="true" background="aquamarine" ></Drawer> </div> </template> <script> export default { data() { return { drawerVisible: false }; }, methods:{ // 打開抽屜 visible() { this.drawerVisible = true; } } } </script>
2.關(guān)閉抽屜
在點(diǎn)擊遮罩層的時候,我們希望可以關(guān)閉已經(jīng)打開的抽屜組件,這里如果你直接修改父組件傳過來的drawerVisible值,會報(bào)錯如下
vue.esm.js:629 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten
whenever the parent component re-renders. Instead, use a data or computed property based on the
prop's value. Prop being mutated: "drawerVisible"
這是因?yàn)関ue是單向數(shù)據(jù)流的,如果想改變父元素的值,必須使用監(jiān)聽事件的方式,但是2.3.0之后添加了.sync修飾符,所以,正確的做法是使用.sync修飾符
... <div v-if="drawerVisible" class="mask"></div> <transition :name="this.direction=='left'?'slide-right':'slide-left'"> <div v-if="drawerVisible" @click.stop="closeBtn?'':close" class="drawer"> <div class="drawer_body" :style="{ 'right':direction=='right'?'0':'auto', 'left':direction=='left'?'0':'auto', 'width':width+'px', 'background': background}" > </div> </div> </transition> ... methods: { close() { this.$emit("update:drawerVisible", false); } }
另外,我們還希望在關(guān)閉抽屜組件時,我們可以監(jiān)聽到這個事件然后做出反應(yīng)
methods: { close() { this.$emit("update:drawerVisible", false); this.$emit("close"); } }
此時需要在抽屜組件上添加
<Drawer :drawerVisible.sync="drawerVisible" @close="close" > </Drawer> methods:{ close(){ // 關(guān)閉抽屜組件時你要做的事 } }
2.動畫
動畫是UI的靈魂,所以接下來給抽屜組件的顯示和隱藏添加動畫,我們使用transition的css動畫做動畫過度效果
//drawer.vue <div class="drawer"> <div class="mask"></div> <!-- 不同方向使用不用的動畫名稱,如果抽屜在左邊,則進(jìn)入方向是朝 → --> <transition :name="this.direction=='left'?'slide-right':'slide-left'"> <div class="drawer_body" v-if="drawerVisible" :style="{'right':direction=='right'?'0':'auto', 'left':direction=='left'?'0':'auto', 'width':width+'px', 'background':background}" >drawer</div> </transition> </div> </template> <style scoped> /* * ... *這里省略了寫過的樣式 */ .slide-right-enter-active, .slide-right-leave-active, .slide-left-enter-active, .slide-left-leave-active { will-change: transform; transition: transform 300ms; position: absolute; width: 100vw; height: 100vh; overflow: hidden; } .slide-right-enter, .slide-right-leave-active { transform: translate(-100%, 0); } .slide-left-leave-active, .slide-left-enter { transform: translate(100%, 0); } </style>
雖然現(xiàn)在已經(jīng)完全實(shí)現(xiàn)了抽屜的功能,但是本著更加精美的原則,我還打算使用slot給它添加辯題和頁腳
3.添加標(biāo)題
標(biāo)題solt的name值是header
添加標(biāo)題的目的是為了讓抽屜組件看起來更加清楚,此外,除了添加標(biāo)題,我還想添加個關(guān)閉按鈕
// 需要添加幾個props屬性 <script> export default { props: { // drawer標(biāo)題 title: String, // 是否顯示關(guān)閉按鈕 closeBtn: { type: Boolean, default: false }, } }; </script>
你可以選擇是否添加標(biāo)題,是否添加關(guān)閉按鈕,值的注意的是如果添加了關(guān)閉按鈕,點(diǎn)擊遮罩層就不會自動關(guān)閉抽屜組件了
<!--這里要啰嗦下布局,如果你只選擇開啟關(guān)閉按鈕,那justify-content布局是flex-end 如果兩者都開啟,那justify-content布局是space-between--> <slot name="header"> <div v-if="title||closeBtn" : class="title" > <div v-if="title">{{title}}</div> <el-button v-if="closeBtn" circle size="mini" icon="el-icon-close" @click="close" ></el-button> </div> </slot>
我是這么做到禁用遮罩層點(diǎn)擊事件的
<div v-if="drawerVisible" @click.stop="closeBtn?'':close" class="mask"></div>
當(dāng)然這些你可以使用具名插槽自定義的
<Drawer :width="400" direction="right" :mask="true" title="抽屜組件" > <div v-slot:header>這里是自定義標(biāo)題</div> <div ></div> </Drawer>
4.添加頁腳
頁腳solt的name值是footer
為了使得頁腳和標(biāo)題有一定的距離,我給主體內(nèi)容添加了最小高度
<div > <slot></slot> </div>
方法是很類似的,只是我多添加了兩個監(jiān)聽事件,確定和取消
//drawer.vue <slot name="footer"> <div class="footer"> <el-button size="mini" type="primary" @click="footerOk">確認(rèn)</el-button> <el-button size="mini" @click="footerCal">取消</el-button> </div> </slot>
//引入的頁面 <Drawer :width="400" direction="right" :mask="true" title="抽屜組件" :footer-ok="footerOk" :footer-cal="footerCal" > </Drawer>
還需要在props中添加對應(yīng)的值
props: { footerOk: Function, footerCal: Function },
關(guān)于頁腳的布局是這樣的
.footer { border-top: 0.1px solid #ddd; display: flex; justify-content: flex-end; padding-top: 10px; }
當(dāng)然這些你也是可以使用具名插槽自定義的
<Drawer :width="400" direction="right" :mask="true" title="抽屜組件" > <div v-slot:header>這里是自定義標(biāo)題</div> <div ></div> <div v-slot:footer>這里是自定義頁腳</div> </Drawer>
5.主體是否可以滾動
前面說過給主體添加了最小高度,但是超過最小高度,可能會被撐開布局,所以我給它添加了滾動功能
// props添加 // 是否開啟滾動 scroll: { type: Boolean, default: false }
在drawer_body的樣式末尾追加overflow-y樣式
<div class="drawer_body" :style="{ 'right':direction=='right'?'0':'auto', 'left':direction=='left'?'0':'auto', 'width':width+'px', 'background': background, 'overflow-y':scroll?'scroll':'hidden'}" > </div>
scroll默認(rèn)是不開啟的,如果你的抽屜要放的內(nèi)容少,就不用理這個屬性,但是當(dāng)內(nèi)容撐開抽屜時記得手動開啟這個功能復(fù)制代碼
6.細(xì)節(jié)的優(yōu)化
這里說下自己的不足之處,并且如何改進(jìn)它
a.滾動條bug
當(dāng)選擇抽屜在右邊時,動畫過程中會出現(xiàn)滾動條,看起來讓我的UI組件大打折扣,針對這個問題我打算在組件中監(jiān)聽drawerVisible,當(dāng)它需要被展示時禁用body的滾動效果,當(dāng)它不需要被展示時,還原body的展示效果
watch: { drawerVisible(n, o) { if (n == true) { document.documentElement.style.overflowY = "hidden"; document.documentElement.style.overflowX = "hidden"; } } },
b.向下冒泡bug
在點(diǎn)擊抽屜以外的區(qū)域可以正常關(guān)閉抽屜,但是我發(fā)現(xiàn)當(dāng)我點(diǎn)擊抽屜非按鈕區(qū)域時,也會關(guān)閉抽屜,這是向下冒泡的bug,這個bug我的解決方案是在drawer_body上添加個無意義的事件,并阻止向上冒泡
<div @click.stop="clickBg_" // 注意這里 class="drawer_body" :style="{ 'right':direction=='right'?'0':'auto', 'left':direction=='left'?'0':'auto', 'width':width+'px', 'background': background, 'overflow-y':scroll?'scroll':'hidden'}" > </div>
二、API文檔
1.屬性
屬性 | 描述 | 類型 | 默認(rèn) |
---|---|---|---|
drawerVisible | 是否顯示drawer | Boolean | false |
direction | drawer方向 | String | left |
width | drawer寬度 | Number | 400 |
background | drawer背景色 | String | #ffffff |
mask | 是否顯示遮罩層 | Boolean | true |
title | drawer標(biāo)題 | Boolean | true |
closeBtn | 是否顯示關(guān)閉按鈕 | String | --- |
scroll | 是否開啟滾動 | Boolean | false |
2.事件
事件 | 描述 | 返回值 |
---|---|---|
close | 監(jiān)聽關(guān)閉事件 | 無 |
footerOk | 頁腳確認(rèn)綁定事件,使用默認(rèn)頁腳時有效 | 無 |
footerCal | 頁腳取消綁定事件,使用默認(rèn)頁腳時有效 | 無 |
3.slot
name | 描述 |
---|---|
header | 頁頭插槽名稱 |
default | 抽屜主體部分,可省略 |
footer | 頁腳插槽名稱 |
注意:插槽里的按鈕都是使用element內(nèi)置的組件,如果你的項(xiàng)目里沒有引入element庫
那最好請使用具名插槽重寫頁頭和頁腳部分
感謝各位的閱讀!關(guān)于“怎樣給element添加一個抽屜組件”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
新聞標(biāo)題:怎樣給element添加一個抽屜組件
分享網(wǎng)址:http://chinadenli.net/article6/giedog.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、標(biāo)簽優(yōu)化、面包屑導(dǎo)航、網(wǎng)站營銷、商城網(wǎng)站、動態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)