通过js方法调用全局组件(如:element-ui $notify)

  • 组件模板
<template>
  <transition name="fade" @after-leave="afterLeaveFn" @after-enter="afterEnterFn">
    <div class="message"
         :style="style"
         v-show="isShow"
         @mouseenter="emptyTimeFn"
         @mouseleave="clearTimeFn"
    >
      <p>{{content}}</p>
      <button @click="ClickCloceFn">{{btn}}</button>
    </div>
  </transition>
</template>

<script>
  export default {
    name: 'message',
    props:{
      content: {
        type: String,
        required:true  // 必填项
      },
      btn: {
        type: String,
        default: '关闭'
      }
    },
    computed:{
      style () {
        return {}
      }
    },
    data () {
      return {
      	// 是否显示该组件(这里为什么不直接写成true, true的情况下,元素在挂载前本事就存在的,所以显示的动画没效果,在extends扩展里改为true 或者挂载后都可以实现)
        isShow: false,
        // 删除的时候拿到该元素的高度用来计算
        height:0,
      }
    },
    methods: {
      // 所有方法尽量去  extends扩展 里写,不熟悉执行流程,可能有些方法不会执行
    },
  }
</script>

<style scoped lang="scss">
  .fade-enter-active, .fade-leave-active {
    transition: opacity .5s
  }
  .fade-enter, .fade-leave-active {
    opacity: 0
  }
  .message{
    width: 200px;
    background: rgb(0,0,0,0.5);
    border-radius: 5%;
    p{
      color: #ffffff;
      padding: 0 10px;
      box-sizing: border-box;
    }
    button{
      position: absolute;
      top: 0;
      right: 0;
    }
  }
</style>
  • 使用基础 Vue 构造器,创建一个“子类”。 extends扩展
import message from "./message";

// 扩展  extends组件可以覆盖样式的好处
export default  {
  extends: message,
  // 覆盖样式
  computed:{
    style () {
      return {
        position: 'fixed',
        top: `${this.offsetHeight}px`,
        right: '20px'
      }
    }
  },
  data () {
    return {
      // 元素的高度
      offsetHeight: 0,
      // 自动关闭的时间  类型:Number
      autoClear: 0,
    }
  },
  methods: {
    // 自动关闭通知栏
    clearTimeFn () {
      if(this.autoClear){
        this.time = setTimeout(()=>{
          this.isShow = false
        },this.autoClear)
      }
    },
    // 清除时间(防止没清除掉,占用内存)
    emptyTimeFn () {
      if(this.time){
        clearTimeout(this.time)
      }
    },
    // 点击关闭按钮
    ClickCloceFn () {
      this.$emit('cloceFn')
    },
    // 动画关闭结束回调函数
    afterLeaveFn () {
      this.$emit('afterLeaveFn')
    },
    // 动画显示后回调函数
    afterEnterFn () {
      this.height = this.$el.offsetHeight
    }
  },
  mounted(){
  	// 自动执行关闭函数
    this.clearTimeFn()
    // 显示组件(这里改为true 就有动画效果了)
    this.isShow = true
  },
  // 销毁回调函数
  beforeDestroy() {
    console.log('已销毁')
    this.emptyTimeFn()
  }
}


  • 通过方法实现动态挂载DOM(可以写你想做的一切事情)
import Vue from "vue";
import Component from './Fn_index'
// 去创建一个组件(用方法调用创建一个组件所以要extend 创建组件) 然后可以通过new 来拿到
const newComponent = Vue.extend(Component)


// 定义一个存放元素(通知)数组,
const instanceArr = [];
let seed = 1;  // 生成不同的ID 用的


// 关闭后要处理的函数(清空元素数组,动态改变元素定位的高度)
const removeFn = (el)=>{
  console.log(el)
  if(!el) return;

  // 获取el在instanceArr的第几个位置
  let idx = instanceArr.findIndex(item => el.id === item.id)
  // 从数组里删除对应的数据
  instanceArr.splice(idx,1);
  // 重新计算高度
  const len = instanceArr.length;
  console.log(len)
  if(len <=0) return;
  const H = el.vm.height + 20;
  // 从删除的地方开始计算
  for (let i=idx; i<len; i++){
    instanceArr[i].offsetHeight = instanceArr[i].offsetHeight - H
  }
};


// 方法
const messageFn = (options) => {
  // 在服务端的时候什么也不做(因为没有dom节点)
  if(Vue.prototype.$isServer) return;

  // new 组件
  const instance = new newComponent({
    propsData: options,
    data: {
      autoClear:options.autoClear?autoClear:3000
    }
  });
  // 赋值ID
  let id = `messagetions_${seed++}`;
  instance.id = id;
  instance.vm = instance.$mount(); // 没参数的时候生成一个节点
  // 挂载到节body点里
  document.body.appendChild(instance.vm.$el);
  // 元素的定位高值
  let heightOffset = 0;
  // 循环拿到每一个存放的元素(并计算它的高度)
  instanceArr.forEach((item,idx)=>{
    heightOffset += item.$el.offsetHeight + 20;
  });
  heightOffset += 20;
  instance.$data.offsetHeight = heightOffset;
  instanceArr.push(instance);

  // 点击关闭
  instance.vm.$on('cloceFn',()=>{
    console.log('cloceFn')
    instance.vm.isShow = false
  });
  // 动画关闭结束回调函数
  instance.vm.$on('afterLeaveFn',()=>{
    console.log('afterLeaveFn')
    removeFn(instance)
    // 删除节点
    document.body.removeChild(instance.vm.$el);
    // 销毁对象
    instance.vm.$destroy()
  });

  return instance.vm
};

export default messageFn

// export default function install() {  // use插件引入
//   Vue.prototype.$loading = messageFn
// }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值