Component library simple development – Toast

Directly on the code:

// index.ts
import { createApp,nextTick,ComponentPublicInstance } from 'vue'
import ToastComponent from './index.vue'
exporttype ToastOptions = { iconName? : string, message? :String, duration? :Number,}export type ComponentInstance = ComponentPublicInstance<{}, any>;
let toastPool:ComponentInstance[] = []
function createInstance() {
    const app = createApp(ToastComponent);
    const root = document.createElement('div');
    document.body.appendChild(root);
    const instance = app.mount(root)
    return instance
}
function getInstance(){
    if(! toastPool.length) {const instance = createInstance();
        toastPool.push(instance);
    }
    return toastPool[toastPool.length - 1];
}
function parseOptions(message: string | ToastOptions) :ToastOptions {
    if(message ! = =null && typeof message === 'object') {return message;
    }
    return { message }
}
function Toast(options: string | ToastOptions = {}){
    const toast = getInstance();
    const parsedOptions:ToastOptions = parseOptions(options);
    Object.assign(toast,parsedOptions)
    nextTick(() = > {
        toast.visible = true
        setTimeout(() = >{
            toast.close()
        }, toast.duration)
    })
    return toast
}
// extension method todo
Toast.success=() = >{}
Toast.fail=() = >{}
Toast.loading=() = >{}
export default Toast
Copy the code
// index.vue
<template>
  <div class="le-toast" v-show="visible">
    <div class="le-toast-box">
      <le-icon class="icon" v-if="iconName" size="40px" :name="iconName" />
      <span class="message">{{ message }}</span>
    </div>
  </div>
</template>
<script lang="ts">
import { defineComponent,toRefs,reactive} from 'vue'
import LeIcon from '@ui/base/icon'
export default defineComponent({
    name:'le-toast'.components: { LeIcon },
    setup() {
        const data = reactive({
            visible:false.iconName:' '.message:' '.duration:2000.close:() = >{
                data.visible = false}})const toRafsData = toRefs(data)
        return {
            ...toRafsData
        }
    }
})
</script>
<style lang="less">
@import './index.less';
</style>
Copy the code
// index.less
@import '@assets/style/var.less';
.le-toast {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  bottom: inherit ! important;
  min-width: 320px;
  max-width: 750px;
  margin: 0 auto;
  box-sizing: border-box;
  z-index: 1001;
  text-align: center;

  &-box {
    width: auto;
    background: rgba(0.0.0.0.7);
    border-radius: 8px;
    padding: 20px;
    font-size: 13px;
    max-width: 282px;
    color: #fff;
    display: inline-block;
    word-break: break-all;
    margin: 0 auto;
    text-align: center;

    .icon {
      display: block;
      font-size: 26px;
      padding: 2px;
      margin-bottom: 8px;
    }

    .message {
      font-size: 14px;
      display: block; }}}Copy the code
import Toast from "@ui/base/toast/index"
app.config.globalProperties.$Toast = Toast
// The usage mode
$Toast('Info info info');
$Toast({
    message:'Hint + icon'.duration:4000.iconName:'success'
})
Copy the code

The effect