vue自定義外掛封裝,實現簡易的elementUi的Message和MessageBox的示例
阿新 • • 發佈:2020-11-23
這次封裝基於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'})
效果如下:
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(() => {});
效果如下
這時,點選確定按鈕就會觸發 .then裡的事件,點選取消則觸發 .catch裡的事件
typescript對應的宣告檔案
typescript書寫自定義外掛對應的宣告檔案,避免編輯報錯
import Vue from "vue"; declare module "vue/types/vue" { interface Vue { $toast: any,$confirm: any } }
以上就是vue自定義外掛封裝,實現簡易的elementUi的Message和MessageBox的示例的詳細內容,更多關於vue自定義外掛封裝的資料請關注我們其它相關文章!