vue3

吐司封装

# 1. index.ts

import { createVNode, render } from 'vue'
import toastTemplate from './index.vue'
export interface IProps {
  message?: string
  duration?: number
  background?: string
  fontColor?: string
  className?: string
  position?: string
}
const defaultOpt = {
  duration: 1500,
}

export interface ResultParams {
  clear?: () => void
}
const Toast = (options: IProps): ResultParams => {
  const container = document.createElement('div')
  container.classList.add('toast-warp')
  const opt = { ...defaultOpt, ...options }
  const vm = createVNode(toastTemplate, opt)
  render(vm, container)
  document.body.appendChild(container)
  /* const innerClear = () => {
    const dom = vm.el as HTMLDivElement
    let diffTime: number = opt.duration - 500 > 500 ? opt.duration - 500 : 500
    if (dom.querySelector('.ac-toast__value')) {
      dom.querySelector('.ac-toast__value')?.classList.remove('slide-down')
      const removeClassTimer = setTimeout(() => {
        dom.querySelector('.ac-toast__value')?.classList.add('reomve')
        clearTimeout(removeClassTimer)
      }, diffTime)

      const removeDomTimer = setTimeout(() => {
        render(null, container)
        document.body.removeChild(container)
        clearTimeout(removeDomTimer)
      }, opt.duration)
    }
  }*/
  if (opt.duration > 0) {
    const timer = setTimeout(() => {
      clear()
      clearTimeout(timer)
    }, opt.duration)
  }
  return {
    clear,
  }
}

const destroyDom = (options: IProps) => {
  const opt = { ...defaultOpt, ...options }
  const toastWarp: any = document.querySelector('.toast-warp')
  let diffTime: number = opt.duration - 500 > 500 ? opt.duration - 500 : 500
  if (document.querySelector('.ac-toast__value')) {
    document.querySelector('.ac-toast__value')?.classList.remove('slide-down')
    const removeClassTimer = setTimeout(() => {
      document.querySelector('.ac-toast__value')?.classList.add('reomve')
      clearTimeout(removeClassTimer)
    }, diffTime)

    const removeDomTimer = setTimeout(() => {
      render(null, toastWarp)
      document.body.removeChild(toastWarp)
      clearTimeout(removeDomTimer)
    }, opt.duration)
  }
}

const clear = () => destroyDom({})
export default Toast

export { clear }

# 2. index.vue

<template>
  <div
    class="ac-toast"
    :style="{ alignItems: position }"
    :class="wrapClassName"
    @click="forbidClick ? close() : ''"
  >
    <div
      class="ac-toast__value slide-down"
      :style="{ background: background, color: fontColor }"
      :class="className"
    >
      {{ message }}
    </div>
  </div>
</template>
<script setup>
import Toast from '@/components/ac-toast/index.ts'
const props = defineProps({
  message: {
    type: String,
    default: ''
  },
  duration: {
    type: Number,
    default: 1500
  },
  background: {
    type: String,
    default: 'rgb(8, 8, 8, 0.7)'
  },
  fontColor: {
    type: String,
    default: '#fff'
  },
  className: {
    type: String,
    default: ''
  },
  wrapClassName: {
    type: String,
    default: '11111'
  },
  position: {
    type: String,
    default: 'flex-start'
  },
  forbidClick: {
    type: Boolean,
    default: false
  }
})
const iDuration = props.duration / 1000 + 's'

const close = () => {}
</script>

<style>
.ac-toast {
  position: fixed;
  top: 10px;
  left: 0;
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
}

.ac-toast__value {
  max-width: 82%;
  padding: 6px 10px;
  border-radius: 4px;
  text-align: center;
  display: inline-block;
}

.slide-down {
  animation: slide-down-in 0.5s;
}

.reomve {
  /* animation: slide-up v-bind('iDuration') 1 ease-out forwards; */
  animation: slide-up-out 0.5s 1 ease-in-out forwards;
}

@keyframes slide-up-out {
  from {
    transform: translateY(0);
    opacity: 1;
  }

  to {
    transform: translateY(-100%);
    opacity: 0;
  }
}

@keyframes slide-down-in {
  0% {
    opacity: 0;
    transform: translateY(-100%);
  }

  100% {
    opacity: 1;
    transform: translateY(0%);
  }
}
</style>

# 3. 页面使用

<script setup>
import Toast, { clear } from '@/components/ac-toast'
const testClick = () => {
  const toast = Toast({
    message: 'toast8',
    duration: 500,
    className: '9999'
  })
  // clear()
}
</script>
上次更新: