Vue組件化開發之通用型彈出框

本文主要分享關於組件化開發的理解,讓剛入門的小夥伴少走一些彎路,提升開發效率,做者本人也是新手,若有不當之處,請大佬指出,感謝。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,而且在父組件若是沒有指定slotv-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-sasssass-loader,如今咱們的頁面是這個樣子了ide

雖然仍是不太美觀,可是已經基本上是一個彈出框的雛形了,而且我沒有給a標記樣式,緣由在後面。

SCSS函數

回過頭再看看上面的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中有transformtransition能夠實現動畫效果,可是咱們這裏使用vue內置組件<transition>,讓彈出框有一個從上面彈出的效果。

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庫同樣去使用它而不須要每次引入。

最後

在實際開發中,組件化是尤其重要的,它可以幫助咱們寫出更高質量的代碼,也可以讓咱們的代碼更易於維護,儘早的樹立組件化的思想,對寫代碼也是很是有幫助的。

本文只是對組件化的簡單理解,有不對的地方,歡迎大佬指出。

感謝評論區大佬的點撥。

但願看完的朋友能夠給個贊,鼓勵一下

附上github.com/anpeier/sho…

相關文章
相關標籤/搜索