美文网首页让前端飞
手写一个基于vue的全局Toast组件吧

手写一个基于vue的全局Toast组件吧

作者: 小鳄鱼的大哥哦 | 来源:发表于2019-05-12 21:17 被阅读1次

    目标文件components/toast文件夹
    main.js

    import Vue from "vue";
    import Main from "./main.vue"; // 引入toast 组件
    
    // extent方法传入一个vue组件,生成一个子实例对象
    // 要求组件中的data必须是函数,也就是为什么我们的组件中的data必须是函数
    let ToastConstructor = Vue.extend(Main);
    
    let instance;
    
    const Toast = function (options = {
        content: '', // 必传参数
        duration: 3000 // 显示时间
    }) {
        // 渲染成Vue组件
        instance = new ToastConstructor({
            data: options // 这里的 data 会传到 main.vue 组件中的 data 中,当然也可以写在 props 里
        });
        // instance.$el是生成的DOM对象,添加到body中
        document.body.appendChild(instance.$mount().$el);
    };
    
    // 以下就是在 Toast 函数中拓展 ["success", "error"] 这两个方法
    let tostTypes = ["success", "error"]
    tostTypes.forEach(type => {
        Toast[type] = options => {
            options.type = type;
            return Toast(options);
        };
    });
    
    // 调用方法this.$Toast.success()...
    export default Toast;
    

    main.vue

    <template>
      <div class="toast" :class="type ? `toast--${type}` : ''">
        <p>{{content}}</p>
      </div>
    </template>
    
    <script>
    export default {
      name: "Toast",
      data(){
          return{
            content: '',
            duration: '',
            type:'',
          }
      },
      mounted() {
        setTimeout(() => {
          // 3s 后通过父级移除子元素的方式来移除该组件实例和 DOM 节点
          this.$destroy(true);
          this.$el.parentNode.removeChild(this.$el);
        }, this.duration);
      }
    };
    </script>
    
    <style lang="scss" scoped>
    .toast {
      display: flex;
      align-items: center;
      justify-content: center;
      position: fixed;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      color: #fff;
      z-index: 9999;
      background: transparent;
      > p {
        padding: 12px 22px;
        font-size: 18px;
        border-radius: 4px;
        background: rgba(17, 17, 17, 0.7);
      }
    
      // error和success的样式
      &--error p { background: rgba(255, 0, 0, 0.5); }
      &--success p { background: rgba(0, 255, 0, 0.5); }
    }
    </style>
    

    根目录下的main.js

    import Vue from 'vue'
    import Toast from './components/toast/main'
    
    Vue.prototype.$toast = Toast
    

    组建中使用

    this.$toast({content: '网络错误',duration: 3000})
    this.$toast.success({content: '网络错误',duration: 3000})
    this.$toast.error({content: '网络错误',duration: 3000})
    

    相关文章

      网友评论

        本文标题:手写一个基于vue的全局Toast组件吧

        本文链接:https://www.haomeiwen.com/subject/pvyggqtx.html