本文主要分享關於組件化開發的理解,讓剛入門的小夥伴少走一些彎路,提升開發效率,做者本人也是新手,若有不當之處,請大佬指出,感謝。javascript
相信不少剛入門的小夥伴,常常會寫不少重複的代碼,而這些代碼通常狀況下也都是大同小異,在這種狀況下,如何讓開發和學習變得更加高效,組件化的思想就顯得尤其重要。這裏經過設計一個簡單的彈出框,給小夥伴們分享組件化的應用。css
組件化是對某些能夠進行復用的功能進行封裝的標準化工做。組件通常會內含自身的內部UI元素、樣式和JS邏輯代碼,它能夠很方便的在應用的任何地方進行快速的嵌入。組件內部可使用其餘組件來構成更復雜的組件。vue
在實際的開發中,咱們應該避免去編寫重複的代碼,將精力放在更加核心的部分,所以就須要將這些重複的代碼抽取出來,封裝成公共的組件,提升開發效率,但同時也要注意組件的健壯性和可複用性,讓它可以儘量適應更多的場景。java
首先是彈出框的基本結構node
<div class="modal">
<div class="mask"></div>
<div class="modal-dialog">
<div class="modal-header">
<span>標題</span>
<a href="javascript:;" class="icon-close"></a>
</div>
<div class="modal-body">
<slot name="body"></slot>
</div>
<div class="modal-footer">
<a href="javascript:;" class="btn">肯定</a>
<a href="javascript:;" class="btn btn-default">取消</a>
</div>
</div>
</div>
</div>
複製代碼
基本結構很簡單,稍微注意一點的就是slot
插槽,若是沒有提供name屬性,它將有一個隱含的名字default,而且在父組件若是沒有指定slot
的v-slot
屬性的話,內容會傳給default插槽。css3
在這裏定義了slot
的name屬性body
,這種的叫作具名插槽,會匹配v-slot:body
的內容。git
注意,在父組件中調用須要用<template>
包裹,而且<template>
元素中的全部內容都將被傳入相應的插槽。github
給彈出框加點樣式sass
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
.mask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #000000;
opacity: 0.5;
}
.modal-dialog {
position: absolute;
top: 40%;
left: 50%;
width: 560px;
height: auto;
background-color: #ffffff;
transform: translate(-50%, -50%);
.modal-header {
height: 60px;
background-color: #F5F5F5;
padding: 0 25px;
line-height: 60px;
font-size: 16px;
.icon-close {
position: absolute;
top: 23px;
right: 25px;
width: 14px;
height: 14px;
background: url("/static/img/icon-close.png") no-repeat center;
background-size: contain;
}
}
.modal-body {
padding: 42px 40px 54px;
font-size: 14px;
}
.modal-footer {
height: 82px;
line-height: 82px;
text-align: center;
background-color: #F5F5F5;
}
}
}
複製代碼
我這裏使用的是scss
,使用的時候別忘了安裝node-sass
和sass-loader
,如今咱們的頁面是這個樣子了ide
雖然仍是不太美觀,可是已經基本上是一個彈出框的雛形了,而且我沒有給a
標記樣式,緣由在後面。
回過頭再看看上面的css
代碼,這裏重複寫了4次固定定位的代碼,並且隨着項目的推動,確定還有更多相似的代碼,何不將這些部分抽取出來,進行封裝呢?scss
提供了這個功能,將css
封裝成函數,這裏的函數直接會返回函數體。咱們在遇到相似的狀況時,就可以直接複用。
在assets
目錄下新建scss
文件夾並在裏面新建mixin.scss
,在裏面新建position
函數,代碼以下:
@mixin position($pos: absolute, $top: 0, $left: 0, $w: 100%, $h: 100%) {
position: $pos;
top: $top;
left: $left;
width: $w;
height: $h;
}
複製代碼
接着咱們引入mixin.scss
,用position
函數替換咱們原先的代碼
經過@include方式使用scss
函數:@include position(fixed);
括號裏面的是參數。
每個網站都有不少按鈕,不過,同一個網站的按鈕風格大多都是同樣,無非是大小不一。所以能夠單獨在scss
文件下新建button.scss
而後在App.vue
裏面引入這個文件,在後面除了一些特別的樣式,其它就不須要給按鈕定義樣式了,這樣也便於維護。這裏給出個人button
文件,能夠參考一下。
.btn {
display: inline-block;
width: 110px;
line-height: 30px;
text-align: center;
background-color: #FF6600;
color: #ffffff;
border: none;
cursor: pointer;
}
.btn-default {
background-color: #b0b0b0;
color: #d7d7d7;
}
.btn-large {
width: 202px;
height: 50px;
line-height: 50px;
font-size: 18px;
}
.btn-huge {
width: 300px;
height: 54px;
line-height: 54px;
font-size: 16px;
}
.btn-group {
.btn {
margin-right: 20px;
&:last-child {
margin-right: 0;
}
}
}
複製代碼
當前這個彈出框還只是一個固定的結構,它並不能在其餘地方複用,須要進行一些處理,將全部可變部分抽取出來,例如標題,按鈕,內容。由於有插槽,因此內容就不用考慮,須要關注的是標題和按鈕,由於標題有多是提示,警告等等,按鈕也有多是肯定、取消的一個或兩個都有。而這些信息都是從父組件傳遞過來,須要用props
接收。
在props
裏面添加以下代碼,並給某些屬性指定默認值:
props: {
// 彈框標題
title: String,
// 按鈕類型: 1:肯定按鈕 2:取消按鈕 3:肯定取消
btnType: String,
// 按鈕文本
sureText: {
type: String,
default: "肯定"
},
cancleText: {
type: String,
default: "取消"
},
showModal: Boolean
}
複製代碼
添加完以後,還需從新改寫代碼
<div class="modal" v-show="showModal">
<div class="mask"></div>
<div class="modal-dialog">
<div class="modal-header">
<span>{{title}}</span>
<a href="javascript:;" class="icon-close" @click="$emit('cancle')"></a>
</div>
<div class="modal-body">
<slot name="body"></slot>
</div>
<div class="modal-footer">
<a href="javascript:;" class="btn" v-if="btnType==1"@click="$emit('submit')"{{sureText}}</a>
<a href="javascript:;" class="btn" v-if="btnType==2"@click="$emit('cancle')">{{cancleText}}</a>
<div class="btn-group" v-if="btnType==3">
<a href="javascript:;" class="btn" @click="$emit('submit')">{{sureText}}</a>
<a href="javascript:;" class="btn btn-default" @click="$emit('submit')">{{cancleText}}</a>
</div>
</div>
</div>
</div>
複製代碼
經過父組件傳遞的參數,來實現代碼的重用,而且使用$emit
來向外拋出自定義事件,而後在父組件實現本身的業務邏輯。
在Home.vue
裏面引入這個組件並調用
<modal
title="小星星"
sureText="肯定"
btnType="1"
:showModal="showModal"
@submit="go"
@cancle="showModal=false"
>
<template v-slot:body>
<p>給個小星星吧</p>
</template>
</modal>
複製代碼
這裏的@submit
和@cancle
就是咱們在組件裏面自定義的事件
最終效果以下
實現完以後,感受有點彈出時生硬,不要緊,咱們給它加點動畫,在css3中有transform
和transition
能夠實現動畫效果,可是咱們這裏使用vue
內置組件<transition>
,讓彈出框有一個從上面彈出的效果。
transition
組件能夠爲元素或組件添加過渡效果,只會把過渡效果應用到其包裹的內容上,而不會額外渲染 DOM 元素,也不會出如今可被檢查的組件層級中。它能夠經過多種方式進行過渡,在這裏應用 class的方式過渡。
這幅圖是Vue
官方給出的圖,簡單來講,v-enter是動畫開始的狀態,v-enter-active進入過渡生效時的狀態,v-enter-to是過渡的結束狀態,leave同理,具體細節你們能夠去cn.vuejs.org/v2/guide/tr…查看。
當沒有指定的name屬性時,過渡的類名會默認以v做爲前綴,這裏給transition指定name爲
slide並用它包裹modal組件
<transition name="slide">
<div class="modal" v-show="showModal">
...
...
</div>
</transition>
複製代碼
在style代碼裏面modal後面加上
&.slide-enter-active {
top: 0;
}
&.slide-leave-active {
top: -100%;
}
&.slide-enter {
top: -100%;
}
複製代碼
而且給modal指定須要過渡的屬性
transition: top 0.5s;
複製代碼
加完這個以後,彈出框就會有一個滑上滑下的動畫啦。
到此,咱們的彈出框就完成啦。
你也能夠根據本身的需求去作適當的調整,開發出適合本身項目的彈出框。
每次在用這個彈出框的時候,還須要引入組件,也顯得有點麻煩,所以,能夠將其作成插件,可以全局調用,而不須要去引入。
在當前目錄下新建index.js,經過使用install方法將其全局註冊
import Modal from './Modal.vue'
const component = {
install: function (Vue) {
Vue.component('Modal', Modal)
}
}
export default component
複製代碼
在main.js引入,並經過Vue.use()來全局使用,這樣就能像其餘ui庫同樣去使用它而不須要每次引入。
在實際開發中,組件化是尤其重要的,它可以幫助咱們寫出更高質量的代碼,也可以讓咱們的代碼更易於維護,儘早的樹立組件化的思想,對寫代碼也是很是有幫助的。
本文只是對組件化的簡單理解,有不對的地方,歡迎大佬指出。
感謝評論區大佬的點撥。