网站首页 » 前端开发 » Vue » Vue 插件开发 Toast
上一篇:
下一篇:

Vue 插件开发 Toast

前言

Vue 插件开发第一篇,这篇来做个简单的例子,Toast 弹窗提示,如果不知道如何制作 Vue 插件,可以看这里《Vue 插件编写的完整套路》。

Vue 插件开发 Toast

基本文件结构
src
   ├── components
   │  ├── DetailPost.vue
   │  ├── EditPost.vue
   │  └── Home.vue
   ├── assets
   │  └── plugins
   │    └── toast.css
   ├── plugins
   │  └── Toast.js
   ├── router
   │  └── index.js
   ├── App.vue
   └── main.js

下面是这个插件的源码

Toast.js
let toast = {
  show(o) {
    let obj = {
      text: "老铁,传点什么吧!", // 默认文字
      position: "center", // 默认位置
      time: 2000, // 默认显示时长
      cusClass: '' // 开发者自定义类
    }
    let toastTimer;
    if (getType(arguments[0]) === "Object" && arguments.length === 1) { // 如果只有一个参数,并且参数对象类型,则直接合并对象
      Object.assign(obj, o);
    } else if (getType(arguments[0]) === "String" && arguments.length === 1) { // 如果只有一个参数,并且参数为字符串类型
      obj.text = arguments[0];
    } else if (getType(arguments[0]) === "String" && getType(arguments[1]) === "Function" && arguments.length === 2) { // 如果有两个参数并且第一个是字符串,第二个是回调则
      let to = {
        text: arguments[0],
        fn: arguments[1]
      }
      Object.assign(obj, to);
    }

    // 根据配置生成生成相应的 html 字符串
    switch (obj.position) {
      case "top":
        generatorHtml("toast-top");
        break;
      case "right":
        generatorHtml("toast-right");
        break;
      case "bottom":
        generatorHtml("toast-bottom");
        break;
      case "left":
        generatorHtml("toast-left");
        break;
      case "center":
        generatorHtml("toast-center");
        break;
      default:
    }

    // 生成 toast html 并添加到页面中
    function generatorHtml(clas) {
      const html = `
        <div class="toast-mask"></div>
        <div class="toast-main ${clas}">
            <div class="toast-inner animated flipInX">
                <span>${obj.text}</span>
           </div>
        </div>`;
      let toastHtml = document.createElement("div");
      if (obj.cusClass) {
        toastHtml.classList.add("toast", obj.cusClass);
      } else {
        toastHtml.classList.add("toast");
      }
      toastHtml.innerHTML = html;
      document.body.appendChild(toastHtml);

      toastTimer = setTimeout(() => {
        clearTimeout(toastTimer);
        document.body.removeChild(toastHtml);
        // 执行回调
        if (obj.fn) {
          obj.fn();
        }
      }, obj.time);
    }

    function getType(object) {
      /**
       * 方法来源:prototype.js
       * getType(5); // => "Number"
       * getType({}); // => "Object"
       * getType(/foo/); // => "RegExp"
       * getType(''); // => "String"
       * getType(true); // => "Boolean"
       * getType([]); // => "Array"
       * getType(undefined); // => "Window"
       * getType(Element); // => "Constructor"
       **/
      return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
    }
  },
}
export
default {
  install: function (vm) {
    vm.prototype.$toast = toast;
  }
}
Toast.css
.toast {
  font-size: 16px;
}

.toast-mask {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: rgba(0, 0, 0, 0);
}

.toast-main {
  position: fixed;
  border-radius: 4px;
}

.toast-top {
  top: 0;
  left: 50%;
  -webkit-transform: translateX(-50%);
  transform: translateX(-50%);
}

.toast-right {
  writing-mode: tb-rl;
  right: 0;
  top: 50%;
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
}

.toast-bottom {
  bottom: 0;
  left: 50%;
  -webkit-transform: translateX(-50%);
  transform: translateX(-50%);
}

.toast-left {
  writing-mode: tb-rl;
  left: 0;
  top: 50%;
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
}

.toast-center {
  left: 50%;
  top: 50%;
  -webkit-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
}

.toast-inner {
  position: relative;
  padding: 10px 12px;
  background: rgba(0, 0, 0, 0.7);
  color: #fff;
  border-radius: 4px;
  /* backface-visibility: hidden;
  -webkit-backface-visibility: hidden; */
  -webkit-transform: translate3d(0, 100px, 0);
  transform: translate3d(0, 0, 0)
}
// 下面的动画类来自animate.css
.animated {
  -webkit-animation-duration: 1s;
  animation-duration: 1s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}

@-webkit-keyframes flipInX {
  from {
    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
    transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
    -webkit-animation-timing-function: ease-in;
    animation-timing-function: ease-in;
    opacity: 0;
  }
  40% {
    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
    transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
    -webkit-animation-timing-function: ease-in;
    animation-timing-function: ease-in;
  }
  60% {
    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
    transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
    opacity: 1;
  }
  80% {
    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
    transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
  }
  to {
    -webkit-transform: perspective(400px);
    transform: perspective(400px);
  }
}

@keyframes flipInX {
  from {
    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
    transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
    -webkit-animation-timing-function: ease-in;
    animation-timing-function: ease-in;
    opacity: 0;
  }
  40% {
    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
    transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
    -webkit-animation-timing-function: ease-in;
    animation-timing-function: ease-in;
  }
  60% {
    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
    transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
    opacity: 1;
  }
  80% {
    -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
    transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
  }
  to {
    -webkit-transform: perspective(400px);
    transform: perspective(400px);
  }
}

.flipInX {
  -webkit-backface-visibility: visible !important;
  backface-visibility: visible !important;
  -webkit-animation-name: flipInX;
  animation-name: flipInX;
}

在 main.js 中像其它插件一样引入模块,Vue.use() 一下就好

import Vue from 'vue'
import App from './App'
import router from './router'
import Toast from '@/plugins/Toast'
import "@/assets/plugins/toast.css"
Vue.config.productionTip = false
Vue.use(Toast);

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: {
    App
  },
  template: '<App/>'
})

用法一:传对象

this.$toast.show({
  text: "用户名不存在",
  position: this.selectType,
  time:1500
});

用法二:传两个参数(第一个是提示语,第二个是回调)

this.$toast.show("用户名不存在", function() {
  consoel.log("用户名不存在");
});

参数说明:

  • text:提示语,可选,有默认值,就看你能不能接受
  • position:提示语显示位置,可选,默认居中显示
  • cusClass:用户自定义类,可选,给最外层 div 添加一个自定义类名
  • fn:回调,可选,提示语消失时的回调
  • time:提示语显示时长,默认为 2000 毫秒

 

 

  • 微信扫一扫,赏我

  • 支付宝扫一扫,赏我

声明

原创文章,不经本站同意,不得以任何形式转载,如有不便,请多多包涵!

本文永久链接:http://yunkus.com/vue-plugins-development-toast/

Leave a Reply

Your email address will not be published. Required fields are marked *

评论 END