封装一个自己的$message

作用:全局可用,无需重复引入组件,可配置执行回调,关闭组件,函数的链式调用

效果:

文件目录:src/component

调用方法:

1.可通过链式调用,

this.$noticeTips.success(。。。)

2.可通过链式调用快捷配置text

this.$noticeTips.success('重置子账号密码成功')

3.可通过链式调用,也可通过属性配置

const noticeOptions = {
        // title: '', //一级标题
        showClose: true, // 是否展示关闭按钮
        text: '子账号新增成功', // 二级标题
        // type: 'warning', //类型
        delay: 5000, // 延迟
        callback: () => {
          this.getData()
        }
      }
this.$noticeTips.success(noticeOptions)

index.js


import Vue from 'vue'
import Notice from './index.vue'
import { isNotEmpty } from '@/utils/util.js'
const NoticeConstructoe = Vue.extend(Notice)
let instance
const NoticeTips = {
  install: (data, type) => {
    // vue会默认给data赋事件
    if (typeof data === 'function') return
    let options = {}
    // noticeTips('。。。。。')
    if (typeof data === 'string') {
      options.text = data
    }
    // 是否链式调用
    if (isNotEmpty(type)) {
      options.type = type
    }
    // noticeTips({text:'.....'})
    if (Object.prototype.toString.call(data) === '[object Object]') {
      options = { ...data, ...options }
    }
    instance = new NoticeConstructoe({
      data: options
    })
    // this.$el 拿到组件实际上的Dom 挂载到body上
    document.body.appendChild(instance.$mount().$el)
    Vue.nextTick(() => {
      instance.show = true
    })
  }
}
Vue.prototype.$noticeTips = NoticeTips.install;

['success', 'error', 'warning'].forEach(item => {
  Vue.prototype.$noticeTips[item] = (content) => {
    return Vue.prototype.$noticeTips(content, item)
  }
})
export default NoticeTips

此文件注意的点是

当我们使用链式调用的时候(.success || .error) 相当于调用的是 第一步 content这个形参就是我们全局调用$noticeTips传的入参 type这个形参相当于遍历这个 ['success', 'error', 'warning'] 把他作为第二个入参 传给index.vue里面

那么第二步就是 第一步调用的函数 data的入参就是接收的content type就是接收的type

链式调用

打印

属性调用

打印

所以这一步的含义,就是链式调用的话我们会整合到data里面传给index.vue

index.vue

<template>
  <transition name="slide-fade">
      <div class="notice-dialog"
        :class="type"
        v-if="show"
       >
      <div class="d-flex align-items-center justify-conent-around">
          <img class="img-icon" :src="iconImg"/>
          <section>
            <div class="one" v-show="title">{{title}}</div>
            <div class="two" v-show="text">{{text}}</div>
          </section>
          <img v-show="showClose" class="close-t" @click="close" src="@/assets/images/order/Close.svg"/>
      </div>
      </div>
  </transition>
</template>
<script>
export default {
  name: 'Notice',
  data() {
    return {
      type: '',
      show: false,
      title: '',
      text: '',
      delay: 5000,
      showClose: true,
      callback: null
    }
  },
  computed: {
    iconImg() {
      const obj = {
        'success': require('@/assets/images/order/success.svg'),
        'warning': require('@/assets/images/order/yellow-blacklist.svg'),
        'error': require('@/assets/images/order/order_error.svg')
      }
      return obj[this.type]
    }
  },
  mounted() {
    setTimeout(() => {
    // document.body.removeChild(instance.$mount().$el)
      this.show = false
      // 结束时调用
      this.callback && this.callback()
    }, this.delay)
  },
  methods: {
    close() {
      this.callback && this.callback()
      this.show = false
    }
  }
}
</script>
<style lang='scss' scoped>
.success{
  background: #10B981;
  border: 1px solid #059669;
}
.warning{
  background: #FBBF24;
  border: 1px solid #F59E0B;
}
.error{
background: #ef4444;
border: 1px solid #ef4444;

}
.notice-dialog {
position: absolute;
padding: 12px;
top: 67px;
right: 23px;
box-sizing: border-box;
z-index: 9999;
border-radius: 6px;
overflow: hidden;
.img-icon {
  width: 32px;
  height: 32px;
  object-fit: cover;
  margin-right: 15px;
}
.one{
  color: #FFF;
  /* Paragraph/P2/Semi Bold */
  font-family: Inter;
  font-size: 16px;
  font-style: normal;
  font-weight: 600;
  margin-bottom: 5px;
}
.two {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-size: 14px;
  line-height: 17px;
  display: flex;
  align-items: center;
  color: #FFFFFF;
}

.close-t {
  margin-left:10px;
  z-index: 111;
  width: 16px;
  height: 16px;
  object-fit: cover;
  cursor: pointer;
  margin-top: -25px;
}
}
/* 可以设置不同的进入和离开动画 */
/* 设置持续时间和动画函数 */
.slide-fade-enter-active {
transition: all .3s ease;
}
.slide-fade-leave-active {
transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to
/* .slide-fade-leave-active for below version 2.1.8 */ {
transform: translateX(10px);
opacity: 0;
}
</style>

index.vue文件需要注意的是

回调函数,传入的话,在组件关闭时,调用就可

我们一定要在文件里面处理关闭时间,如果在index,js里面处理的话,当我们触发多个的时候,会生成多个示例,会导致关闭的就只有一个,其他的组件还木讷的回显在那,但是我们写在vue文件里的话,每次都会执行

最后我们在main.js 全局引用就行

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值