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开发chrome插件,实现获取界面数据和保存到数据库功能
Dec 01 Vue.js
浅谈Vue使用Elementui修改默认的最快方法
Dec 05 Vue.js
详解vue-cli项目在IE浏览器打开报错解决方法
Dec 10 Vue.js
Vue在H5 项目中使用融云进行实时个人单聊通讯
Dec 14 Vue.js
Vue组件简易模拟实现购物车
Dec 21 Vue.js
vue watch监控对象的简单方法示例
Jan 07 Vue.js
vue浏览器返回监听的具体步骤
Feb 03 Vue.js
详解Vue.js 可拖放文本框组件的使用
Mar 03 Vue.js
vue中data改变后让视图同步更新的方法
Mar 29 Vue.js
vue+spring boot实现校验码功能
May 27 Vue.js
Vue全局事件总线你了解吗
Feb 24 Vue.js
vue实现移动端div拖动效果
Mar 03 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编程最快明白》第四讲:日期、表单接收、session、cookie
2010/11/01 PHP
关于PHP模板Smarty的初级使用方法以及心得分享
2013/06/21 PHP
PHP判断访客是否手机端(移动端浏览器)访问的方法总结【4种方法】
2019/03/27 PHP
laravel 查询数据库获取结果实现判断是否为空
2019/10/24 PHP
JavaScript arguments 多参传值函数
2010/10/24 Javascript
jquery模拟按下回车实现代码
2011/09/20 Javascript
JS获取节点的兄弟,父级,子级元素的方法
2014/01/09 Javascript
全面兼容的javascript时间格式化函数(比较实用)
2014/05/14 Javascript
使用script的src实现跨域和类似ajax效果
2014/11/10 Javascript
JS基于Ajax实现的网页Loading效果代码
2015/10/27 Javascript
JS如何判断是否为ie浏览器的方法(包括IE10、IE11在内)
2015/12/13 Javascript
JavaScript程序开发之JS代码放置的位置
2016/01/15 Javascript
AngularJS中使用HTML5手机摄像头拍照
2016/02/22 Javascript
vue.js入门教程之计算属性
2016/09/01 Javascript
javascript cookie基础应用之记录用户名的方法
2016/09/20 Javascript
js判断PC端与移动端跳转
2020/12/24 Javascript
Node.JS利用PhantomJs抓取网页入门教程
2017/05/19 Javascript
JavaScript异步上传图片文件的实例代码
2017/07/04 Javascript
Angular在模板驱动表单中自定义校验器的方法
2017/08/09 Javascript
微信小程序的日期选择器的实例详解
2017/09/29 Javascript
Electron vue的使用教程图文详解
2019/07/05 Javascript
webpack 如何解析代码模块路径的实现
2019/09/04 Javascript
小程序实现点击tab切换左右滑动
2020/11/16 Javascript
JS实现鼠标移动拖尾
2020/12/27 Javascript
使用Kivy将python程序打包为apk文件
2017/07/29 Python
Python3.6日志Logging模块简单用法示例
2018/06/14 Python
python3 字符串/列表/元组(str/list/tuple)相互转换方法及join()函数的使用
2019/04/03 Python
Python从文件中读取指定的行以及在文件指定位置写入
2019/09/06 Python
Python Print实现在输出中插入变量的例子
2019/12/25 Python
谈谈Python:为什么类中的私有属性可以在外部赋值并访问
2020/03/05 Python
美国在线轮胎零售商:SimpleTire
2019/04/08 全球购物
三月法制宣传月活动总结
2014/07/03 职场文书
政风行风整改方案
2014/10/25 职场文书
2015年公司后勤管理工作总结
2015/05/13 职场文书
复兴之路展览观后感
2015/06/02 职场文书
初一数学教学反思
2016/02/17 职场文书