zoukankan      html  css  js  c++  java
  • vue 自定义 提示框(Toast)组件

    1.自定义 提示框 组件

    src / components / Toast / index.js

    /**
     * 自定义 提示框( Toast )组件
     */
    var Toast = {};
    var showToast = false, // 存储toast显示状态
      showLoad = false, // 存储loading显示状态
      toastVM = null, // 存储toast vm
      loadNode = null; // 存储loading节点元素
     
    Toast.install = function (Vue, options) {
      // 参数
      var opt = {
        defaultType: 'bottom',
        duration: '2500',
        wordWrap: false
      };
      for (var property in options) {
        opt[property] = options[property];
      }
     
      Vue.prototype.$toast = function (tips, type) {
     
        var curType = type ? type : opt.defaultType;
        var wordWrap = opt.wordWrap ? 'lx-word-wrap' : '';
        var style = opt.width ? 'style=" ' + opt.width + '"' : '';
        var tmp = '<div v-show="show" :class="type" class="lx-toast ' + wordWrap + '" ' + style + '>{{tip}}</div>';
     
        if (showToast) {
          // 如果toast还在,则不再执行
          return;
        }
        if (!toastVM) {
          var toastTpl = Vue.extend({
            data: function () {
              return {
                show: showToast,
                tip: tips,
                type: 'lx-toast-' + curType
              }
            },
            template: tmp
          });
          toastVM = new toastTpl()
          var tpl = toastVM.$mount().$el;
          document.body.appendChild(tpl);
        }
        toastVM.type = 'lx-toast-' + curType;
        toastVM.tip = tips;
        toastVM.show = showToast = true;
     
        setTimeout(function () {
          toastVM.show = showToast = false;
        }, opt.duration)
      };
     
      ['bottom', 'center', 'top'].forEach(function (type) {
        Vue.prototype.$toast[type] = function (tips) {
          return Vue.prototype.$toast(tips, type)
        }
      });
     
      Vue.prototype.$loading = function (tips, type) {
        if (type == 'close') {
          loadNode.show = showLoad = false;
        } else {
          if (showLoad) {
            // 如果loading还在,则不再执行
            return;
          }
          var loadTpl = Vue.extend({
            data: function () {
              return {
                show: showLoad
              }
            },
            template: '<div v-show="show" class="lx-load-mark"><div class="lx-load-box"><div class="lx-loading"><div class="loading_leaf loading_leaf_0"></div><div class="loading_leaf loading_leaf_1"></div><div class="loading_leaf loading_leaf_2"></div><div class="loading_leaf loading_leaf_3"></div><div class="loading_leaf loading_leaf_4"></div><div class="loading_leaf loading_leaf_5"></div><div class="loading_leaf loading_leaf_6"></div><div class="loading_leaf loading_leaf_7"></div><div class="loading_leaf loading_leaf_8"></div><div class="loading_leaf loading_leaf_9"></div><div class="loading_leaf loading_leaf_10"></div><div class="loading_leaf loading_leaf_11"></div></div><div class="lx-load-content">' + tips + '</div></div></div>'
          });
          loadNode = new loadTpl();
          var tpl = loadNode.$mount().$el;
     
          document.body.appendChild(tpl);
          loadNode.show = showLoad = true;
        }
      };
     
      ['open', 'close'].forEach(function (type) {
        Vue.prototype.$loading[type] = function (tips) {
          return Vue.prototype.$loading(tips, type)
        }
      });
    }
     
    // 向外暴露接口
    module.exports = Toast;

    src / components / Toast / toast.css

    /**
     * Toast 样式
     */
    .lx-toast {
      position: fixed;
      bottom: 100px;
      left: 50%;
      box-sizing: border-box;
      max- 80%;
      height: 40px;
      line-height: 20px;
      padding: 10px 20px;
      transform: translateX(-50%);
      -webkit-transform: translateX(-50%);
      text-align: center;
      z-index: 9999;
      font-size: 14px;
      color: #fff;
      border-radius: 5px;
      background: rgba(0, 0, 0, 0.7);
      animation: show-toast .5s;
      -webkit-animation: show-toast .5s;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
     
    .lx-toast.lx-word-wrap {
       80%;
      white-space: inherit;
      height: auto;
    }
     
    .lx-toast.lx-toast-top {
      top: 50px;
      bottom: inherit;
    }
     
    .lx-toast.lx-toast-center {
      top: 50%;
      margin-top: -20px;
      bottom: inherit;
    }
     
    @keyframes show-toast {
      from {
        opacity: 0;
        transform: translate(-50%, -10px);
        -webkit-transform: translate(-50%, -10px);
      }
      to {
        opacity: 1;
        transform: translate(-50%, 0);
        -webkit-transform: translate(-50%, 0);
      }
    }
     
    .lx-load-mark {
      position: fixed;
      left: 0;
      top: 0;
       100%;
      height: 100%;
      z-index: 9999;
    }
     
    .lx-load-box {
      position: fixed;
      z-index: 3;
       7.6em;
      min-height: 7.6em;
      top: 180px;
      left: 50%;
      margin-left: -3.8em;
      background: rgba(0, 0, 0, 0.7);
      text-align: center;
      border-radius: 5px;
      color: #FFFFFF;
    }
     
    .lx-load-content {
      margin-top: 64%;
      font-size: 14px;
    }
     
    .lx-loading {
      position: absolute;
       0px;
      left: 50%;
      top: 38%;
    }
     
    .loading_leaf {
      position: absolute;
      top: -1px;
      opacity: 0.25;
    }
     
    .loading_leaf:before {
      content: " ";
      position: absolute;
       9.14px;
      height: 3.08px;
      background: #d1d1d5;
      box-shadow: rgba(0, 0, 0, 0.0980392) 0px 0px 1px;
      border-radius: 1px;
      -webkit-transform-origin: left 50% 0px;
      transform-origin: left 50% 0px;
    }
     
    .loading_leaf_0 {
      -webkit-animation: opacity-0 1.25s linear infinite;
      animation: opacity-0 1.25s linear infinite;
    }
     
    .loading_leaf_0:before {
      -webkit-transform: rotate(0deg) translate(7.92px, 0px);
      transform: rotate(0deg) translate(7.92px, 0px);
    }
     
    .loading_leaf_1 {
      -webkit-animation: opacity-1 1.25s linear infinite;
      animation: opacity-1 1.25s linear infinite;
    }
     
    .loading_leaf_1:before {
      -webkit-transform: rotate(30deg) translate(7.92px, 0px);
      transform: rotate(30deg) translate(7.92px, 0px);
    }
     
    .loading_leaf_2 {
      -webkit-animation: opacity-2 1.25s linear infinite;
      animation: opacity-2 1.25s linear infinite;
    }
     
    .loading_leaf_2:before {
      -webkit-transform: rotate(60deg) translate(7.92px, 0px);
      transform: rotate(60deg) translate(7.92px, 0px);
    }
     
    .loading_leaf_3 {
      -webkit-animation: opacity-3 1.25s linear infinite;
      animation: opacity-3 1.25s linear infinite;
    }
     
    .loading_leaf_3:before {
      -webkit-transform: rotate(90deg) translate(7.92px, 0px);
      transform: rotate(90deg) translate(7.92px, 0px);
    }
     
    .loading_leaf_4 {
      -webkit-animation: opacity-4 1.25s linear infinite;
      animation: opacity-4 1.25s linear infinite;
    }
     
    .loading_leaf_4:before {
      -webkit-transform: rotate(120deg) translate(7.92px, 0px);
      transform: rotate(120deg) translate(7.92px, 0px);
    }
     
    .loading_leaf_5 {
      -webkit-animation: opacity-5 1.25s linear infinite;
      animation: opacity-5 1.25s linear infinite;
    }
     
    .loading_leaf_5:before {
      -webkit-transform: rotate(150deg) translate(7.92px, 0px);
      transform: rotate(150deg) translate(7.92px, 0px);
    }
     
    .loading_leaf_6 {
      -webkit-animation: opacity-6 1.25s linear infinite;
      animation: opacity-6 1.25s linear infinite;
    }
     
    .loading_leaf_6:before {
      -webkit-transform: rotate(180deg) translate(7.92px, 0px);
      transform: rotate(180deg) translate(7.92px, 0px);
    }
     
    .loading_leaf_7 {
      -webkit-animation: opacity-7 1.25s linear infinite;
      animation: opacity-7 1.25s linear infinite;
    }
     
    .loading_leaf_7:before {
      -webkit-transform: rotate(210deg) translate(7.92px, 0px);
      transform: rotate(210deg) translate(7.92px, 0px);
    }
     
    .loading_leaf_8 {
      -webkit-animation: opacity-8 1.25s linear infinite;
      animation: opacity-8 1.25s linear infinite;
    }
     
    .loading_leaf_8:before {
      -webkit-transform: rotate(240deg) translate(7.92px, 0px);
      transform: rotate(240deg) translate(7.92px, 0px);
    }
     
    .loading_leaf_9 {
      -webkit-animation: opacity-9 1.25s linear infinite;
      animation: opacity-9 1.25s linear infinite;
    }
     
    .loading_leaf_9:before {
      -webkit-transform: rotate(270deg) translate(7.92px, 0px);
      transform: rotate(270deg) translate(7.92px, 0px);
    }
     
    .loading_leaf_10 {
      -webkit-animation: opacity-10 1.25s linear infinite;
      animation: opacity-10 1.25s linear infinite;
    }
     
    .loading_leaf_10:before {
      -webkit-transform: rotate(300deg) translate(7.92px, 0px);
      transform: rotate(300deg) translate(7.92px, 0px);
    }
     
    .loading_leaf_11 {
      -webkit-animation: opacity-11 1.25s linear infinite;
      animation: opacity-11 1.25s linear infinite;
    }
     
    .loading_leaf_11:before {
      -webkit-transform: rotate(330deg) translate(7.92px, 0px);
      transform: rotate(330deg) translate(7.92px, 0px);
    }
     
    @-webkit-keyframes opacity-0 {
      0% {
        opacity: 0.25;
      }
      0.01% {
        opacity: 0.25;
      }
      0.02% {
        opacity: 1;
      }
      60.01% {
        opacity: 0.25;
      }
      100% {
        opacity: 0.25;
      }
    }
     
    @-webkit-keyframes opacity-1 {
      0% {
        opacity: 0.25;
      }
      8.34333% {
        opacity: 0.25;
      }
      8.35333% {
        opacity: 1;
      }
      68.3433% {
        opacity: 0.25;
      }
      100% {
        opacity: 0.25;
      }
    }
     
    @-webkit-keyframes opacity-2 {
      0% {
        opacity: 0.25;
      }
      16.6767% {
        opacity: 0.25;
      }
      16.6867% {
        opacity: 1;
      }
      76.6767% {
        opacity: 0.25;
      }
      100% {
        opacity: 0.25;
      }
    }
     
    @-webkit-keyframes opacity-3 {
      0% {
        opacity: 0.25;
      }
      25.01% {
        opacity: 0.25;
      }
      25.02% {
        opacity: 1;
      }
      85.01% {
        opacity: 0.25;
      }
      100% {
        opacity: 0.25;
      }
    }
     
    @-webkit-keyframes opacity-4 {
      0% {
        opacity: 0.25;
      }
      33.3433% {
        opacity: 0.25;
      }
      33.3533% {
        opacity: 1;
      }
      93.3433% {
        opacity: 0.25;
      }
      100% {
        opacity: 0.25;
      }
    }
     
    @-webkit-keyframes opacity-5 {
      0% {
        opacity: 0.270958333333333;
      }
      41.6767% {
        opacity: 0.25;
      }
      41.6867% {
        opacity: 1;
      }
      1.67667% {
        opacity: 0.25;
      }
      100% {
        opacity: 0.270958333333333;
      }
    }
     
    @-webkit-keyframes opacity-6 {
      0% {
        opacity: 0.375125;
      }
      50.01% {
        opacity: 0.25;
      }
      50.02% {
        opacity: 1;
      }
      10.01% {
        opacity: 0.25;
      }
      100% {
        opacity: 0.375125;
      }
    }
     
    @-webkit-keyframes opacity-7 {
      0% {
        opacity: 0.479291666666667;
      }
      58.3433% {
        opacity: 0.25;
      }
      58.3533% {
        opacity: 1;
      }
      18.3433% {
        opacity: 0.25;
      }
      100% {
        opacity: 0.479291666666667;
      }
    }
     
    @-webkit-keyframes opacity-8 {
      0% {
        opacity: 0.583458333333333;
      }
      66.6767% {
        opacity: 0.25;
      }
      66.6867% {
        opacity: 1;
      }
      26.6767% {
        opacity: 0.25;
      }
      100% {
        opacity: 0.583458333333333;
      }
    }
     
    @-webkit-keyframes opacity-9 {
      0% {
        opacity: 0.687625;
      }
      75.01% {
        opacity: 0.25;
      }
      75.02% {
        opacity: 1;
      }
      35.01% {
        opacity: 0.25;
      }
      100% {
        opacity: 0.687625;
      }
    }
     
    @-webkit-keyframes opacity-10 {
      0% {
        opacity: 0.791791666666667;
      }
      83.3433% {
        opacity: 0.25;
      }
      83.3533% {
        opacity: 1;
      }
      43.3433% {
        opacity: 0.25;
      }
      100% {
        opacity: 0.791791666666667;
      }
    }
     
    @-webkit-keyframes opacity-11 {
      0% {
        opacity: 0.895958333333333;
      }
      91.6767% {
        opacity: 0.25;
      }
      91.6867% {
        opacity: 1;
      }
      51.6767% {
        opacity: 0.25;
      }
      100% {
        opacity: 0.895958333333333;
      }
    }
    View Code

    2.全局引入

    main.js

    // 全局引入Toast
    import './components/Toast/toast.css';
    import Toast from './components/Toast/index';
    Vue.use(Toast);

    3.页面调用

    Toast.vue

    <!-- 提示框 -->

    <template>
      <div>
        <!-- 标题栏 -->
        <mt-header title="提示框">
          <router-link to="/" slot="left">
            <mt-button icon="back">返回</mt-button>
          </router-link>
        </mt-header>
        <!-- 内容 -->
        <button @click="openTop()">top</button>
        <button @click="openCenter()">center</button>
        <button @click="openBottom()">bottom</button>
        <button @click="openLoading()">loading</button>
      </div>
    </template>
     
    <script>
      export default {
        name: 'Toast',
        data(){
          return {
            //
          }
        },
        methods:{
          openTop(){
            this.$toast.top('top');
          },
          openCenter(){
            this.$toast.center('center');
          },
          openBottom(){
            this.$toast('bottom');  // or this.$toast.bottom('bottom');
          },
          openLoading(){
            this.$loading('loading...');
            let self = this;
            setTimeout(function () {
              self.closeLoading()
            }, 2000)
          },
          closeLoading(){
            this.$loading.close();
          }
        }
      }
    </script>
     
    <style lang="less" scoped>
      //
    </style>
     
    4.效果图
     
  • 相关阅读:
    Oracle
    CCF 201609-5 祭坛
    prometheus同时执行多个查询
    压力测试 Apache ab
    kubernetes reference
    python 深拷贝
    [ argo workflow ]
    django orm 改动数据库中已存在的表(添加、删除、修改表字段)migrations
    内存压力测试命令
    django 未成功初始化自定义表单
  • 原文地址:https://www.cnblogs.com/maqingyuan/p/9494064.html
Copyright © 2011-2022 走看看