vue自定义插件封装,实现简易的elementUi的Message和MessageBox的示例


Posted in Vue.js onNovember 20, 2020

这次封装基于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, Vue, 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, 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, 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自定义插件封装的资料请关注三水点靠木其它相关文章!

Vue.js 相关文章推荐
Vue项目利用axios请求接口下载excel
Nov 17 Vue.js
element-plus一个vue3.xUI框架(element-ui的3.x 版初体验)
Dec 02 Vue.js
vue3.0中setup使用(两种用法)
Dec 02 Vue.js
浅析vue中的nextTick
Dec 28 Vue.js
Vuex实现简单购物车
Jan 10 Vue.js
Vue实现下拉加载更多
May 09 Vue.js
Vue如何实现组件间通信
May 15 Vue.js
Vue项目打包、合并及压缩优化网页响应速度
Jul 07 Vue.js
vue如何实现关闭对话框后刷新列表
Apr 08 Vue.js
vue自定义右键菜单之全局实现
Apr 09 Vue.js
VUE解决跨域问题Access to XMLHttpRequest at
May 06 Vue.js
Vue Mint UI mt-swipe的使用方式
Jun 05 Vue.js
详解vue 组件注册
Nov 20 #Vue.js
vue-drawer-layout实现手势滑出菜单栏
Nov 19 #Vue.js
Vue 打包的静态文件不能直接运行的原因及解决办法
Nov 19 #Vue.js
如何使用 vue-cli 创建模板项目
Nov 19 #Vue.js
深入了解Vue3模板编译原理
Nov 19 #Vue.js
vue 获取到数据但却渲染不到页面上的解决方法
Nov 19 #Vue.js
vue 插槽简介及使用示例
Nov 19 #Vue.js
You might like
超外差式晶体管收音机的组装与统调
2021/03/01 无线电
咖啡豆的最常见发酵处理方法,详细了解一下
2021/03/03 冲泡冲煮
php去除HTML标签实例
2013/11/06 PHP
php对二维数组进行相关操作(排序、转换、去空白等)
2015/11/04 PHP
php字符串的替换,分割和连接方法
2016/05/23 PHP
PHP载入图像imagecreatefrom_gif_jpeg_png系列函数用法分析
2016/11/14 PHP
jquery tablesorter.js 支持中文表格排序改进
2009/12/09 Javascript
浅析Prototype的模板类 Template
2011/12/07 Javascript
JS多物体 任意值 链式 缓冲运动
2012/08/10 Javascript
获取3个数组不重复的值的具体实现
2013/12/30 Javascript
JS中自定义定时器让它在某一时刻执行
2014/09/02 Javascript
详解如何构建Angular项目目录结构
2017/07/13 Javascript
深入浅出es6模板字符串
2017/08/26 Javascript
详解vue mint-ui源码解析之loadmore组件
2017/10/11 Javascript
vue-swiper的使用教程
2018/08/30 Javascript
详解JavaScript中操作符和表达式
2018/09/12 Javascript
简单了解微信小程序的目录结构
2019/07/01 Javascript
微信小程序渲染性能调优小结
2019/07/30 Javascript
Element MessageBox弹框的具体使用
2020/07/27 Javascript
[01:05:24]Ti4 冒泡赛第二天 iG vs NEWBEE 3
2014/07/15 DOTA
详解Python中的from..import绝对导入语句
2016/06/21 Python
Python 实现数据库(SQL)更新脚本的生成方法
2017/07/09 Python
Django实现分页功能
2018/07/02 Python
Python使用logging模块实现打印log到指定文件的方法
2018/09/05 Python
Python实现ATM系统
2020/02/17 Python
Python MOCK SERVER moco模拟接口测试过程解析
2020/04/13 Python
Notino法国:购买香水和化妆品
2019/04/15 全球购物
毕业生找工作推荐信
2013/11/21 职场文书
高中军训感想800字
2014/02/23 职场文书
2014年学校后勤工作总结
2014/12/06 职场文书
优秀党务工作者先进事迹材料
2014/12/25 职场文书
病危通知书样本
2015/04/17 职场文书
平凡的世界读书笔记
2015/06/25 职场文书
假如给我三天光明读书笔记
2015/06/26 职场文书
python文件目录操作之os模块
2021/05/08 Python
《仙剑客栈2》第一弹正式宣传片公开 年内发售
2022/04/07 其他游戏