vue3封装全局消息提示实例

345 阅读1分钟

vue3封装全局消息提示实例

效果展示

实现

模版

模版部分比较简单,里面就是一个msg,用v-show控制展示,外面再包一个Transition动画组件。

<template>
  <Transition>
    <div class="toast_wrp" v-show="isShow">
      <div :class="['toast_inner', 'toast_inner-' + type]">
        {{ msg }}
      </div>
    </div>
  </Transition>
</template>

逻辑代码

包含组件定义和组件注册两块。组件Toast定义比较简单,props参数只需要msg内容和type类型。data中isShow用来控制展示。在组件mounted后,修改isShow字段进行展示。

组件注册部分,使用了vue的createVNode和render函数,并且设置了globalProperties来注册全局函数。

为了把组件挂载到页面上,首先创建一个div节点,并把它插入body中。 然后创建Toast的虚拟节点,并挂载到div上。这样就能在页面上显示出消息组件了。

为了实现消息组件延迟一定时间后自动移除的效果,设置了一个定时器,在默认1000ms后,把空节点挂载到div上。

<script>
import { createVNode, render } from 'vue';

const Toast = {
  name: 'mp-toast',
  props: {
    msg: {
      // toast 显示的wording
      type: String,
      default: '',
    },
    // 类型, success/error
    type: {
      type: String,
      default: 'success',
    },
  },
  data() {
    return {
      isShow: false,
    };
  },
  mounted() {
    this.isShow = true;
  },
};

// 创建消息提示节点
const div = document.createElement('div');
document.body.appendChild(div);

const Message = ({ msg, type, duration }) => {
  let timer = null;
  // 渲染虚拟节点
  const vnode = createVNode(Toast, { msg, type, duration });
  render(vnode, div);
  clearTimeout(timer);
  // 渲染空节点
  timer = setTimeout(() => {
    render(null, div);
  }, duration || 1000);
};

Toast.install = (app) => {
  // 注册全局属性
  app.config.globalProperties.$message = Message;
};
export default Toast;
</script>

样式

.toast_wrp {
  background-color: white;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  opacity: 1;
  visibility: visible;
  z-index: 50000;
  transition: all 0.2s 0.2s;
}
.toast_inner {
  padding: 16px 32px;
  color: white;
  font-size: 17px;
  font-weight: 500;
  border-radius: 10px;
  border: 1px solid white;
}
.toast_inner-success {
  background: rgb(240, 249, 235);
  border-color: rgb(225, 243, 216);
  color: #67c23a;
}
.toast_inner-error {
  background: rgb(254, 240, 240);
  border-color: rgb(253, 226, 226);
  color: #f56c6c;
}
.v-enter-active,
.v-leave-active {
  transition: opacity 0.5s ease;
}

.v-enter-from,
.v-leave-to {
  transform: translate3d(0, -75px, 0);
  opacity: 0;
}

使用

组件需要在全局注册,使用app.use()。

import { createApp } from 'vue';
import App from './App.vue';
import Toast from './components/Toast.vue';

const app = createApp(App);
// 注册Toast组件
app.use(Toast);

app.mount('#app');

注册了之后,在其它地方使用this.$message()就可以创建一个消息实例了。

也可以在setup函数中访问组件实例对象

import { getCurrentInstance } from 'vue'
setup(){
   const instance= getCurrentInstance();
   instance.proxy.$message({ msg: '复制失败', type: 'error' })
 } 

参考文章

掘金链接:Vue3封装 Message消息提示实例函数