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的hash值原理也是table切换实例代码
Dec 14 Vue.js
vue 通过base64实现图片下载功能
Dec 19 Vue.js
vue中封装axios并实现api接口的统一管理
Dec 25 Vue.js
vue实现登录功能
Dec 31 Vue.js
vue+element table表格实现动态列筛选的示例代码
Jan 14 Vue.js
Vite和Vue CLI的优劣
Jan 30 Vue.js
vue前端和Django后端如何查询一定时间段内的数据
Feb 28 Vue.js
vue组件的路由高亮问题解决方法
May 11 Vue.js
如何用vue实现网页截图你知道吗
Nov 17 Vue.js
Vue的生命周期一起来看看
Feb 24 Vue.js
vue实现滑动解锁功能
Mar 03 Vue.js
Vue OpenLayer测距功能的实现
Apr 20 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中$_SERVER的详细参数与说明介绍
2013/10/26 PHP
PHP图片上传代码
2013/11/04 PHP
浅析js封装和作用域
2013/07/09 Javascript
浅析JavaScript中的CSS属性及命名规范
2013/11/28 Javascript
js中arguments的用法(实例讲解)
2013/11/30 Javascript
基于jquery实现瀑布流布局
2020/06/28 Javascript
JavaScript中输出信息的方法(信息确认框-提示输入框-文档流输出)
2016/06/12 Javascript
最实用的jQuery分页插件
2016/10/09 Javascript
Bootstrap列表组学习使用
2017/02/09 Javascript
详解VUE的状态控制与延时加载刷新
2017/03/27 Javascript
AngularJS页面传参的5种方式
2017/04/01 Javascript
laydate 显示结束时间不小于开始时间的实例
2017/08/11 Javascript
Mobile Web开发基础之四--处理手机设备的横竖屏问题
2017/08/11 Javascript
vue项目首屏加载时间优化实战
2019/04/23 Javascript
详谈Vue.js框架下main.js,App.vue,page/index.vue之间的区别
2020/08/12 Javascript
python连接mongodb操作数据示例(mongodb数据库配置类)
2013/12/31 Python
Python中列表、字典、元组、集合数据结构整理
2014/11/20 Python
用Python实现服务器中只重载被修改的进程的方法
2015/04/30 Python
Python3连接MySQL(pymysql)模拟转账实现代码
2016/05/24 Python
Python实现的凯撒密码算法示例
2018/04/12 Python
在Python中字典根据多项规则排序的方法
2019/01/21 Python
Python实现的爬取小说爬虫功能示例
2019/03/30 Python
Django CSRF跨站请求伪造防护过程解析
2019/07/31 Python
python 解决pycharm运行py文件只有unittest选项的问题
2020/09/01 Python
Anaconda的安装与虚拟环境建立
2020/11/18 Python
以特惠价提供在线奢侈品购物:FRMODA.com
2018/01/25 全球购物
汽车技术服务与营销专业在籍生自荐信
2013/09/28 职场文书
班长岗位职责
2013/11/10 职场文书
心碎乌托邦的创业计划书范文
2013/12/26 职场文书
优秀共产党员先进事迹
2014/01/27 职场文书
应聘会计求职信
2014/06/11 职场文书
热情服务标语
2014/10/07 职场文书
2015年度考核个人工作总结
2015/10/24 职场文书
详解如何修改nginx的默认端口
2021/03/31 Servers
简单介绍Python的第三方库yaml
2021/06/18 Python
Mysql关于数据库是否应该使用外键约束详解说明
2021/10/24 MySQL