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自定义插件封装,实现简易的elementUi的Message和MessageBox的示例
Nov 20 Vue.js
Vue3配置axios跨域实现过程解析
Nov 25 Vue.js
解决Vue-cli3没有vue.config.js文件夹及配置vue项目域名的问题
Dec 04 Vue.js
Vue实现小购物车功能
Dec 21 Vue.js
Vue3 实现双盒子定位Overlay的示例
Dec 22 Vue.js
vue实现简易的双向数据绑定
Dec 29 Vue.js
vue3 watch和watchEffect的使用以及有哪些区别
Jan 26 Vue.js
Vue 实现可视化拖拽页面编辑器
Feb 01 Vue.js
vue脚手架项目创建步骤详解
Mar 02 Vue.js
一篇文章学会Vue中间件管道
Jun 20 Vue.js
vue如何使用模拟的json数据查看效果
Mar 31 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
收听短波不可能有声音清晰的品质吗
2021/03/01 无线电
PHP+JS实现大规模数据提交的方法
2015/07/02 PHP
PHP INT类型在内存中占字节详解
2019/07/20 PHP
JavaScript入门教程(12) js对象化编程
2009/01/31 Javascript
Javascript 匿名函数及其代码模式原理
2010/03/19 Javascript
jquery之empty()与remove()区别说明
2010/09/10 Javascript
五个jQuery图片画廊插件 推荐
2011/05/12 Javascript
一个网页标题title的闪动提示效果实现思路
2014/03/22 Javascript
jQuery前端框架easyui使用Dialog时bug处理
2014/12/05 Javascript
深入探寻javascript定时器
2015/01/02 Javascript
Javascript函数式编程语言
2015/10/11 Javascript
JS实现浏览器状态栏显示时间的方法
2015/10/27 Javascript
javascript+html5+css3自定义弹出窗口效果
2017/10/26 Javascript
在layui下对元素进行事件绑定的实例
2019/09/06 Javascript
js正则匹配多个全部数据问题
2019/12/20 Javascript
ES6 proxy和reflect的使用方法与应用实例分析
2020/02/15 Javascript
使用jquery实现轮播图效果
2021/01/02 jQuery
[01:14:30]TNC vs VG 2019国际邀请赛淘汰赛 胜者组赛BO3 第二场 8.20.mp4
2019/08/22 DOTA
python 从远程服务器下载东西的代码
2013/02/10 Python
浅谈Python的异常处理
2016/06/19 Python
Python中join函数简单代码示例
2018/01/09 Python
python实现手机通讯录搜索功能
2018/02/22 Python
python+ffmpeg视频并发直播压力测试
2018/03/06 Python
TensorFlow实现简单卷积神经网络
2018/05/24 Python
11个Python Pandas小技巧让你的工作更高效(附代码实例)
2019/04/30 Python
DataFrame.groupby()所见的各种用法详解
2020/06/14 Python
如何启动时不需输入用户名与密码
2014/05/09 面试题
简述数组与指针的区别
2014/01/02 面试题
如何写出好的Java代码
2014/04/25 面试题
师范应届生求职信
2013/11/15 职场文书
餐饮业员工工作决心书
2014/03/11 职场文书
公司投资建议书
2014/05/16 职场文书
群众路线教师自我剖析材料
2014/09/29 职场文书
SQL Server作业失败:无法确定所有者是否有服务器访问权限的解决方法
2021/06/30 SQL Server
NodeJs使用webpack打包项目的方法详解
2022/02/28 NodeJs
Mysql表数据比较大情况下修改添加字段的方法实例
2022/06/28 MySQL