简述

在此文章中,我将实现一个类似elplus的message组件,代码十分简单。

实现

我使用的是vnode方式

  • Tip.vue
<script setup>
import { onMounted, ref } from 'vue'
import Icon from '../Icon.vue'

defineProps(['type', 'str', 'withIcon'])
const visible = ref(false)

onMounted(() => visible.value = true)
setTimeout(() => visible.value = false, 3000)
</script>

<template>
  <Transition name="translate">
    <div @click="visible = false" class="pop-message" :class="type" v-show="visible">
      <Icon v-if="withIcon" :icon-name="type"></Icon>
      <span class="text">{{ str }}</span>
    </div>
  </Transition>
</template>

<style scoped lang="scss">
.pop-message {
  position: fixed;
  z-index: 9999;
  top: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  gap: 8px;
  border-radius: 2 px;
  left: 50%;
  transform-origin: center center;
  transform: translate(-50%, 0);
  box-shadow: 0px 5px 10px rgba(54, 83, 56, 0.3);
}

.translate-enter-active,
.translate-leave-active {
  transition: transform 0.5s ease, opacity 0.5s ease;
}

.translate-enter-from,
.translate-leave-to {
  transform: translate(-50%, -30px);
  opacity: 0;
}

.translate-enter-to,
.translate-leave-from {
  transform: translate(-50%, 0x);
  opacity: 1;
}

.text {
  margin: 5px 15px;
}

.warn {
  color: #e6a23c;
  background-color: #fdf6ec;
}

.error {
  color: #f56c6c;
  background-color: #fef0f0;
}

.success {
  color: #64ae40;
  background-color: #fefffd;
}
</style>
  • Icon.vue
<!--  -->
<script setup>
defineProps(['iconName'])
</script>

<template>
  <div class="icon" :style="`mask-image:url(/static/svg/${iconName}.svg)`"></div>
</template>

<style scoped lang="scss">
.icon {
  mask-repeat: no-repeat;
  mask-position: center;
  display: inline-block;
  width: 15px;
  height: 15px;
  background-color: var(--icon-bgc);
}
</style>

  • index.js
import { createVNode, render } from 'vue'
import component from './Tip.vue'

function tip(str, type, withIcon = false) {

  const div = document.createElement('div')
  document.body.appendChild(div)
  const vNode = createVNode(component, { type, str, withIcon })
  render(vNode, div)

  const timer = setTimeout(() => {
    render(null, div)
    clearTimeout(timer)
  }, 3500)
}

export default {
  warn: (str, withIcon = false) => tip(str, 'warn', withIcon),
  success: (str, withIcon = false) => tip(str, 'success', withIcon),
  error: (str, withIcon = false) => tip(str, 'error', withIcon)
}

使用

import Tip from '@/components/tip'

 Tip.success('登录成功', true)
posted on 2025-02-12 14:50  落寞的雪  阅读(66)  评论(0)    收藏  举报