1. 程式人生 > >論如何用Vue實現一個彈窗-一個簡單的元件實現

論如何用Vue實現一個彈窗-一個簡單的元件實現

前言

最近在使用element-ui框架,用到了Dialog對話方塊元件,大致實現的效果,跟我之前自己在移動端專案裡面弄的一個彈窗元件差不太多。然後就想著把這種彈窗元件的實現方式與大家分享一下,下面本文會帶著大家手摸手實現一個彈窗元件。

本文主要內容會涉及到彈窗遮罩的實現,slot插槽的使用方式,props$emit傳參,具體元件程式碼也傳上去了。如果喜歡的話可以點波贊/關注,支援一下,希望大家看完本文可以有所收穫。

元件最後實現的效果

實現步驟

  1. 先搭建元件的html和css樣式,遮罩層和內容層。
  2. 定製彈窗內容:彈窗元件通過slot插槽接受從父元件那裡傳過來彈窗內容。
  3. 定製彈窗樣式:彈窗元件通過props接收從父元件傳過來的彈窗寬度,上下左右的位置。
  4. 元件開關:通過父元件傳進來的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-indexbackground達到遮罩的效果,具體內容的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>

在父元件中的使用方式:
1. 將彈窗元件引入要使用的元件中,並通過components註冊成為元件。
2. 父元件中彈窗元件插槽的使用方法如下。

    <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的使用方式,以彈窗元件為例:

  1. 首先需要在被傳入的元件中定義props的一些特性,驗證之類的。
  2. 然後在父元件中繫結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

參考資料:

相關推薦

如何用Vue實現一個-一個簡單元件實現

前言 最近在使用element-ui框架,用到了Dialog對話方塊元件,大致實現的效果,跟我之前自己在移動端專案裡面弄的一個彈窗元件差不太多。然後就想著把這種彈窗元件的實現方式與大家分享一下,下面本文會帶著大家手摸手實現一個彈窗元件。 本文主要內容會涉及到

從零開始徒手擼一個vue的toast元件

相信普通的vue元件大家都會寫,定義 -> 引入 -> 註冊 -> 使用,行雲流水,一氣呵成,但是如果我們今天是要自定義一個彈窗元件呢? 首先,我們來分析一下彈窗元件的特性(需求): 0. 輕量 –一個元件小於 1Kib (實際打包完不到0

vuevue-cli+bootstarp手動寫一個響應式的導航條

一、應用場景 在很多時候,我們的網站都是要求設計成響應式 也就是網站可以適應於 PC 端、平板和手機端 關於響應式的設計網上有很多教程,大致分為兩種: 1.使用一套程式碼,利用媒體查詢來適配不同的螢幕 2.使用兩套程式碼,根據使用者的終端不同切載入不同的程式碼來適配 兩種

JavaScript封裝自己的一個,是雙按鈕的,比較簡單一些 ,其中引用了jQuery來寫的方法,最後暴露出去,有更好的建議歡迎評論 。。。。

$(function(){ // 設定自執行函式 (function(jQuery){ // 定義建構函式 var Popup = function (title,text,fn) { this.title = title || '

利用js實現popup

settings element type 路由 數據庫 點擊 ack get 事件 簡單實現一個通過一個網頁,點擊生成一個彈窗,然後點擊保存之後自動關閉彈窗的功能。 首先在settings文件中寫上兩條對應的路由關系。 1 urlpatterns = [ 2

CSS實現tost效果

html: <div class="black-and-white-b"> <div class="hintBox"></div> </div>  css: .bla

初學者使用react+antd實現表格+

初學者使用react+antd實現表格+彈窗 github地址: https://github.com/YepFury/react-table-demo 趁著專案間歇,試著寫了一下未接觸的react,找了一下資料,決定使用ant-design元件庫,因為基本是完全的react新手,因此對

使用風格的Activity實現萬能+Service中隱式啟動Activity實現Service中彈

一、使用彈窗風格的Activity先看效果圖程式碼實現:1.在values資料夾的styles.xml中定義彈窗style<style name="DialogStyle" parent="Base.Theme.AppCompat.Dialog"> <!--

c語言實現無限

#include <windows.h> #pragma comment (lib, "User32.lib") int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow

JDBC:Servlet返回資訊到頁面,實現Js效果

//返回資訊,實現頁面彈窗 response.setCharacterEncoding("utf-8"); //防止ajax返回的資料亂碼(有中文的情況下,就必須要寫) response.setCont

基於PopWindow+Listview實現選擇的介面實現

最近在Android專案中用到了基於彈窗(PopWIndow)+ Listview結合的彈窗選項框的介面。 1. MainActivity package com.steven.popwindowtest; import android.app.ActionBar; i

js實現window 小案例

首先大家先看一下這個小案例的效果圖,可能大家剛看到下面這張效果圖的時候有點小小的疑惑,小編在這向大家解釋下,所謂的window彈窗事件就是在圖片的左邊有個選擇按鈕,當我們點選該按鈕時候就會彈出右邊的圖

jquery 實現

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html

DIV+CSS實現中間效果

css程式碼 <style type="text/css" > body{ font-family: "Microsoft YaHei" ! important; } /*灰色遮

JQuery實現效果

這是筆者實際專案中的一個需求,我們先來看看特效。 頁面載入時彈出視窗,點選關閉按鈕,視窗消失並呈現動畫效果。 實現程式碼如下: <!DOCTYPE HTML PUBLIC "-//W3C

Android介面回撥總結,以及運用到PopWindow的Demo實現

背景: 最近專案中接觸到介面回撥,以及Android彈窗PopWindow元件的使用,現在利用學到的知識自己寫了一個簡單的Demo,練習下在Android下如何運用介面回撥,來實現彈窗PopWindow的功能。 程式碼結構: 1. 定義一個介面:OnSelectIt

vue+element 封裝

子元件: <template>     <el-dialog title=""

SSM框架整合實現增刪改查(簡單實現

SSM框架整合實現增刪改查 檔案結構 POM檔案 <packaging>war</packaging> <!-- 處理亂碼 --> <properties> <!-- 設定專案字符集 -->

Vue實現一個全選指令

lld http 做了 hbm n) 功能 sin fur sbc 最近用vue做了兩個項目,都需要實現全選反選的功能,兩個項目用了兩種實現方法,第一個項目用vue的computed,第二個項目用指令來實現,用起來,發覺指令更加方便。 第一次做全選的時候是剛開始接觸vue不

vue2.x註冊一個全局的alert組件

lsa ext one eight ref over 回調函數 pos leave 一、在實際的開發當中,彈窗是少不了的,默認系統的彈窗樣式太醜,難以滿足項目的實際需求,所以需要自己定義彈窗組件,把彈窗組價定義為全局的,這樣減少每次使用的時候引入麻煩,節省開發時間。本文將分