jlzzjlzz亚洲乱熟在线播放

系統城裝機大師 - 唯一官網:www.farandoo.com!

當前位置:首頁 > 腳本中心 > 其它 > 詳細頁面

封裝Vue Element的dialog彈窗組件

時間:2020-09-01來源:www.farandoo.com作者:電腦系統城

我本沒有想著說要封裝一個彈窗組件,但有同行的朋友在問我,而且彈窗組件也確實在項目開發中用的比較多。思前想后,又本著樣式統一且修改起來方便的原則,還是再為大家分享一個我所封裝的彈窗組件吧。

其實,并不是所有封裝組件的方式都是一成不變的,你可以采用函數式組件這種能提高性能的方式,也可以使用帶有狀態和生命周期的普通組件的封裝方式。但像dialog這種包含很多點擊事件如確定或提交事件、取消或重置事件、右上角那個小叉叉的關閉事件等,又有可能包含嵌套其他組件如表格組件、表單組件、樹形組件、穿梭框組件等的公共組件,其成分略微復雜,功能不太單一,你若要采用函數式組件的方式來封裝也不是不可以,只是可能xue微要麻煩一些,我自己建議是不采用這種封裝方式,就采用普通的封裝方式就好。

至于普通組件的封裝方式,我想大家平時在開發的過程中對所接觸的普通組件即帶有狀態和生命周期,也能快樂地使用this關鍵詞的組件已經是非常熟悉了,所以這種封裝方式我就不會再做過多的介紹了。以下是具體的實現過程。

照例還是想來張效果圖:

1、所封裝的彈窗組件dialog.vue

<template>
  <el-dialog
    top="20vh"
    class="el-dialog-cus"
    v-bind="{...$attrs, ...{title, width, center}}"
    :visible="visible"
    :before-close="beClose"
    append-to-body
  >
    <slot></slot>
    <div slot="footer">
      <el-button @click="cancel" plain>{{btnTxt[0]}}</el-button>
      <el-button @click="confirm" type="primary" v-if="btnTxt[1]">{{btnTxt[1]}}</el-button>
    </div>
  </el-dialog>
</template>

<script>
export default {
  inheritAttrs: false,
  props: {
    title: {
      type: String,
      default: "提示",
    },
    width: {
      type: String,
      default: "420px",
    },
    center: {
      type: Boolean,
      default: true,
    },
    autoClose: {
      type: Boolean,
      default: true,
    },
    beforeClose: {
      type: Function,
      default: () => {}
    },
    btnTxt: {
      type: Array,
      default: () => ["取消", "確定"],
    },
  },
  data() {
    return {
      visible: false,
    };
  },
  methods: {
    open(ok) {
      this.ok = ok;
      this.visible = true;
    },
    cancel() {
      this.visible = false;
    },
    confirm() {
      let cancel = () => this.cancel();
      this.ok(cancel);
      this.autoClose && cancel();
    },
    beClose(done) {
      done();
      this.beforeClose();
      this.cancel();
    },
  },
};
</script>

<style lang="scss">
.el-dialog-cus {
  .el-dialog {
    padding: 8px;
  }
  .el-dialog__title {
    font-weight: bold;
  }
  .el-dialog__header {
    padding: 20px 0 12px;
  }
  .el-dialog__headerbtn {
    top: 8px;
    right: 8px;
  }
  .el-dialog--center .el-dialog__body {
    padding: 0 24px;
    text-align: center;
  }
  .el-dialog__footer {
    padding: 20px;
    .el-button {
      padding: 8px 20px;
      & + .el-button {
        margin-left: 40px;
      }
    }
  }
}
</style>

對于以上的一些代碼,我需要做一些特別的說明:

open(ok) {
   this.ok = ok;
   this.visible = true;
}

這段代碼是彈出彈窗的方法,為的是在使用彈窗組件時,我們只需點擊一個按鈕并使用ref來獲取彈窗組件的這個方法即可打開彈窗,剩下的關閉彈窗的操作就交給彈窗的確定或取消按鈕來完成即可。我們不用再額外的寫關閉彈窗的方法并將關閉彈窗的props參數傳給彈窗組件。另外,在打開彈窗的方法中我還保存了一個ok事件,這個ok事件是用于在點擊了彈窗組件的確定或提交按鈕后所觸發的回調方法,比如我們點擊了彈窗的提交按鈕,我們需要調一個接口來完成數據的存儲或修改,那么這個ok事件就是為它實現的,畢竟彈窗組件充當的只是一個我們用于處理業務邏輯的中間橋梁。

confirm() {
   let cancel = () => this.cancel();
   this.ok(cancel);
   this.autoClose && cancel();
}

這段代碼是在點擊彈窗的確定或提交按鈕時觸發的,但為什么要給一個之前保存的ok回調函數傳一個關閉的方法參數呢,這是因為有時我們在點擊了確定或提交的按鈕后并不想立即關閉這個彈窗,而是想在幾秒鐘的倒計時后再關閉這個彈窗并跳轉到其他頁面,亦或是在A彈窗的基礎上又彈出另外一個B彈窗,在B彈窗的基礎上又彈出一個C彈窗。關閉C彈窗時,還能看到B彈窗,而不用在A彈窗的基礎上通過點擊事件再彈出B彈窗。這個時候就需要把關閉的方法當作參數傳遞給ok回調函數,讓調用彈窗組件的人自行控制在什么時候關閉彈窗,這難道不香嗎?只不過這個時候可能需要多給彈窗組件傳一個參數autoClose來通知它是不是需要前端自行控制什么時候來關閉彈窗,畢竟彈窗組件在大多數情況下都是點擊了確定或提交按鈕后就直接被關閉了。

beClose(done) {
   done();
   this.beforeClose();
   this.cancel();
}

這段代碼是彈窗組件的關閉前before-close方法,element的官方解釋是“關閉前的回調,會暫停Dialog的關閉”,官方還給了一個特別的說明:

before-close僅當用戶通過點擊關閉圖標或遮罩關閉Dialog時起效。如果你在footer具名slot里添加了用于關閉Dialog的按鈕,那么可以在按鈕的點擊回調函數里加入before-close的相關邏輯。

它接收一個參數done,用于關閉Dialog。而this.beforeClose()是用來自定義關閉前所要做的一些事情的方法。

還有一點需要注意的是:普通組件所有未聲明的屬性都會被解析到$attrs里面,并自動掛載到組件根元素上面。因為本次封裝的彈窗組件的外面已經沒有根元素了,也就是標簽el-dialog的外面沒有再包裹一層div標簽,所以前邊這句話的意義已經不大了。如果標簽el-dialog的外面又包裹了一層div,那么那句話就有意義了,也就是說這些未聲明的屬性也會出現在最外層的div上,如果不想讓這些未聲明的屬性也出現在最外層的div上,那么就可以用inheritAttrs:false來禁止。但本次封裝的彈窗組件的外面沒有根元素,所以加不加這個inheritAttrs:false都無所謂了。

2、彈窗組件的使用:

<template>
  <div>
    <el-button @click="open">點我打開</el-button>
    <Dialog ref="dialog" :title="title" :width="width" :center="center" :btnTxt="btnTxt" :beforeClose="beforeClose"><span>this is a dialog</span></Dialog>
  </div>
</template>

<script>
import Dialog from "@/components/dialog";

export default {
  components: {
    Dialog,
  },
  data() {
    return {
      width: '500px',
      title: '溫馨提示',
      center: true,
      btnTxt: ['取消', '提交'],
    };
  },
  methods: {
    open() {
      this.$refs.dialog.open(cancel => {
        // cancel();
        console.log('點擊提交按鈕了')
      });
    },
    beforeClose(){
      console.log('關閉前');
    },
  }
};
</script>

以上具體的使用方法中:

open() {
   this.$refs.dialog.open(cancel => {
     // cancel();
     console.log('點擊提交按鈕了')
   });
}

這段代碼就是用來打開或彈出彈窗組件,這里就是采用ref來獲取彈窗組件的open方法,并向彈窗組件的open方法傳一個回調函數,而這個回調函數的參數就是組件中ok事件觸發時所返回的函數參數cancel,如果不需要前端來自行控制彈窗的關閉,則不接收這個cancel參數即可。

分享到:

相關信息

系統教程欄目

欄目熱門教程

人氣教程排行

站長推薦

熱門系統下載