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单元格多列合并的实现
Nov 26 Vue.js
Vue如何实现验证码输入交互
Dec 07 Vue.js
Vue如何跨组件传递Slot的实现
Dec 14 Vue.js
vue 数据操作相关总结
Dec 17 Vue.js
vue实现轮播图帧率播放
Jan 26 Vue.js
基于vue的video播放器的实现示例
Feb 19 Vue.js
vue项目实现分页效果
Mar 24 Vue.js
vue路由实现登录拦截
Mar 24 Vue.js
Vue Element UI自定义描述列表组件
May 18 Vue.js
vue数据字典取键值项目的字典问题
Apr 12 Vue.js
vue实现省市区联动 element-china-area-data插件
Apr 22 Vue.js
Vue router配置与使用分析讲解
Dec 24 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
php下尝试使用GraphicsMagick的缩略图功能
2011/01/01 PHP
深入PHP magic quotes的详解
2013/06/17 PHP
php创建和删除目录函数介绍和递归删除目录函数分享
2014/11/18 PHP
PHP简单数据库操作类实例【支持增删改查及链式操作】
2016/10/10 PHP
php实现微信发红包功能
2018/07/13 PHP
Laravel 框架返回状态拦截代码
2019/10/18 PHP
JavaScript 不只是脚本
2007/05/30 Javascript
JavaScript的类型转换(字符转数字 数字转字符)
2010/08/30 Javascript
jQuery代码优化 遍历篇
2011/11/01 Javascript
jQuery中(function(){})()执行顺序的理解
2013/03/05 Javascript
js实现单一html页面两套css切换代码
2013/04/11 Javascript
禁止iframe脚本弹出的窗口覆盖了父窗口的方法
2014/09/06 Javascript
JS实现CheckBox复选框全选全不选功能
2015/05/06 Javascript
window.onload绑定多个事件的两种解决方案
2016/05/15 Javascript
Javascript基础_简单比较undefined和null 值
2016/06/14 Javascript
深入理解javascript的getTime()方法
2017/02/16 Javascript
VUE利用vuex模拟实现新闻点赞功能实例
2017/06/28 Javascript
js实现鼠标移动到图片产生遮罩效果
2017/10/21 Javascript
获取本机IP地址的实例(JavaScript / Node.js)
2017/11/24 Javascript
vue中使用echarts制作圆环图的实例代码
2018/07/27 Javascript
javascript 关于赋值、浅拷贝、深拷贝的个人理解
2019/11/01 Javascript
ant design 日期格式化的实现
2020/10/27 Javascript
vue 解决IOS10低版本白屏的问题
2020/11/17 Javascript
Python入门及进阶笔记 Python 内置函数小结
2014/08/09 Python
Python脚本实现集群检测和管理功能
2015/03/06 Python
Python脚本实现Web漏洞扫描工具
2016/10/25 Python
python2.7+selenium2实现淘宝滑块自动认证功能
2018/02/24 Python
Python实现堡垒机模式下远程命令执行操作示例
2019/05/09 Python
韩国女装NO.1网店:STYLENANDA
2016/09/16 全球购物
学习决心书
2014/03/11 职场文书
经贸专业毕业生求职信
2014/03/23 职场文书
团结演讲稿范文
2014/05/23 职场文书
中职招生先进个人材料
2014/08/31 职场文书
写给医院的感谢信
2015/01/22 职场文书
售后服务质量承诺书
2015/04/29 职场文书
致青春观后感
2015/06/09 职场文书