1. 程式人生 > 程式設計 >vue自定義外掛封裝,實現簡易的elementUi的Message和MessageBox的示例

vue自定義外掛封裝,實現簡易的elementUi的Message和MessageBox的示例

  這次封裝基於vuecli3 + typescript實現,javascript也是同理,沒有區別;

  自定義外掛有助於我們可以將一些頁面互動封裝並在js或ts檔案中引入實現,而不是隻在 .vue檔案。

1、實現toast外掛封裝(類似簡易版的elementUi的message)

  先書寫一個toast元件

<template>
  <div ref="toastRef" class="toastMessageBox">{{ message }}</div>
</template>

<script lang="ts">
import { Component,Vue,Watch } from 'vue-property-decorator';
@Component({})
export default class toast extends Vue {
  message: string = '';
  type: string = '';

  mounted() {
    let ele: HTMLElement = <HTMLElement>this.$refs.toastRef;
    if (this.type === 'success') {
      ele.style.backgroundColor = '#f0f9eb';
      ele.style.borderColor = '#e1f3d8';
      ele.style.color = '#67c23a';
    } else if (this.type === 'error') {
      ele.style.backgroundColor = '#fef0f0';
      ele.style.borderColor = '#fde2e2';
      ele.style.color = '#f56c6c';
    }
  }

  showToast() {
    let ele: HTMLElement = <HTMLElement>this.$refs.toastRef;
    ele.style.top = '20px';
    ele.style.opacity = '1';
  }

  hideToast() {
    let ele: HTMLElement = <HTMLElement>this.$refs.toastRef;
    ele.style.top = '-100px';
    ele.style.opacity = '0';
  }
}
</script>

<style scoped lang="scss">
.toastMessageBox {
  position: fixed;
  min-width: 380px;
  left: 50%;
  z-index: 999;
  -webkit-transform: translateX(-50%);
  transform: translateX(-50%);
  color: #fff;
  padding: 15px 15px 15px 20px;
  font-size: 16px;
  border-radius: 4px;
  opacity: 0;
  top: -100px;
  transition: opacity 0.3s,top 0.4s;
  color: #909399;
  background-color: #edf2fc;
  border: 1px solid #ebeef5;
}
</style>

然後書寫對應的toast.ts

import Vue from 'vue';
// toast元件
import toastComponent from '@/components/toast/index.vue'

// 返回一個 擴充套件例項構造器
const ToastConstructor = Vue.extend(toastComponent)

// 定義彈出元件的函式 接收2個引數,要顯示的文字 和 顯示時間
function showToast(data: { message: any,type: string,duration?: number }) {

  // 例項化一個 toast.vue
  const toastDom: any = new ToastConstructor({
    el: document.createElement('div'),data() {
      return {
        message: data.message,type: data.type,}
    }
  });

  // 把 例項化的 toast.vue 新增到 body 裡
  document.body.appendChild(toastDom.$el);
  setTimeout(() => { toastDom.showToast(); })

  // 過了 duration 時間後隱藏
  let duration = data.duration ? data.duration : 2000
  setTimeout(() => {
    toastDom.hideToast();
    setTimeout(() => {
      document.body.removeChild(toastDom.$el)
    },500)
  },duration)
}
// 註冊為全域性元件的函式
function registryToast() {
  // 將元件註冊到 vue 的 原型鏈裡去,// 這樣就可以在所有 vue 的例項裡面使用 this.$toast()
  Vue.prototype.$toast = showToast
}
export default registryToast;

然後在main.ts中註冊

// 自定義toast外掛
import toastMessage from '@/utils/toast.ts';
Vue.use(toastMessage)

然後就可以在全域性地方使用

this.$toast({message:"成功",type:'success'})

效果如下:

vue自定義外掛封裝,實現簡易的elementUi的Message和MessageBox的示例

2、實現$confirm外掛封裝(類似簡易版的elementUi的messageBox)

  主要用於操作的二次確定

還是一樣,首先書寫confirm元件

這裡按鈕點選事件我設定了一個callback回撥,用於方便後面的操作互動

<template>
  <div class="confirm-wrapper" @click="confirmClick($event)">
    <div class="confirm-box" ref="confirmBox">
      <p class="confirm-title">
        {{ title }}
      </p>
      <p class="content-text">
        {{ contentText }}
      </p>
      <div class="footer-button">
        <ck-button size="mini" @click="close">取消</ck-button>
        <ck-button size="mini" class="define-button" type="primary" @click="define">確定</ck-button>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { Component,Watch } from 'vue-property-decorator';
@Component({})
export default class confirm extends Vue {
  title: string = '提示';
  contentText: string = '';
  callback: any = null;

  confirmClick(e: any) {
    let confirmBox = this.$refs.confirmBox;
    if (e.target.contains(confirmBox)) {
      (<HTMLElement>this.$el.parentNode).removeChild(this.$el);
    }
  }

  define() {
    (<HTMLElement>this.$el.parentNode).removeChild(this.$el);
    this.callback('confirm');
  }

  close() {
    (<HTMLElement>this.$el.parentNode).removeChild(this.$el);
    this.callback('cancel');
  }
}
</script>

<style scoped lang="scss">
.confirm-wrapper {
  position: fixed;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  background: rgba(0,0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  .confirm-box {
    width: 420px;
    padding-bottom: 10px;
    vertical-align: middle;
    background-color: #fff;
    border-radius: 4px;
    border: 1px solid #ebeef5;
    font-size: 18px;
    box-shadow: 0 2px 12px 0 rgba(0,0.1);
    text-align: left;
    overflow: hidden;
    backface-visibility: hidden;
    .confirm-title {
      padding: 15px 15px 10px;
      font-size: 18px;
    }
    .content-text {
      padding: 10px 15px;
      color: #606266;
      font-size: 14px;
    }
    .footer-button {
      padding-top: 24px;
      display: flex;
      justify-content: flex-end;
      padding-right: 24px;
      .define-button {
        margin-left: 16px;
      }
    }
  }
}
</style>

對應的書寫confirm.ts

這裡使用Promise來為使用者點選確定或者取消做對應的互動觸發

import Vue from 'vue';
import confirm from '@/components/confirm/index.vue';
const confirmConstructor = Vue.extend(confirm);

const showConfirm = (contentText: string) => {
  return new Promise((reslove,reject) => {
    const confirmDom: any = new confirmConstructor({
      el: document.createElement('template'),data() {
        return {
          contentText,}
      },})
    confirmDom.callback = (action: string) => {
      if (action === 'confirm') {
        reslove()
      } else if (action === 'cancel') {
        reject()
      }
    }
    document.body.appendChild(confirmDom.$el);
  })
}

function registryConfirm() {
  // 將元件註冊到 vue 的 原型鏈裡去,// 這樣就可以在所有 vue 的例項裡面使用 this.$toast()
  Vue.prototype.$confirm = showConfirm
}
export default registryConfirm;

接下來在main.ts中

import registryConfirm from '@/utils/confirm.ts';
Vue.use(registryConfirm)

然後就可以在全域性使用

this.$confirm('是否確認刪除')
  .then(() => {
    this.$toast({
      message: '刪除成功',type: 'success',});
  })
  .catch(() => {});

效果如下

vue自定義外掛封裝,實現簡易的elementUi的Message和MessageBox的示例

這時,點選確定按鈕就會觸發 .then裡的事件,點選取消則觸發 .catch裡的事件

typescript對應的宣告檔案

typescript書寫自定義外掛對應的宣告檔案,避免編輯報錯

import Vue from "vue";
declare module "vue/types/vue" {
  interface Vue {
    $toast: any,$confirm: any
  }
}

以上就是vue自定義外掛封裝,實現簡易的elementUi的Message和MessageBox的示例的詳細內容,更多關於vue自定義外掛封裝的資料請關注我們其它相關文章!