• 封装一个vue3 Toast组件,支持组件和api调用


    先来看一段代码

    components/toast/index.vue

    <template>
      <div v-if="isShow" class="toast">
        {{msg}}
      div>
    template>
    
    <script setup>
    import { ref, watch } from 'vue'
    const props = defineProps({
      show: {
        type: Boolean,
        default: false
      },
      msg: {
        type: String,
        default: 'message',
      },
      duration: {
        type: Number,
        default: 1500
      }
    })
    
    const isShow = ref(props.show)
    const emit = defineEmits(['update:show'])
    
    watch(() => props.show, (newVal, oldVal) => {
      isShow.value = newVal
      if (newVal) {
        clearInterval(timer)
        var timer = setTimeout(() => {
          isShow.value = false
          emit('update:show', false)
        }, props.duration)
      }
    })
    script>
    
    <style scoped>
      .toast {
        position: fixed;
        top: 200px;
        left: 50%;
        transform: translateX(-50%);
        padding: 4px 8px;
        background-color: rgba(0, 0, 0, .8);
        border-radius: 4px;
        color: #fff;
      }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    这就是一个普通的Toast组件

    • show:是否显示
    • msg:弹窗内容
    • duration:多少毫秒后自动关闭

    调用组件

    views/toast.view

    <template>
      <Toast v-model:show="isShow" msg="hello toast" :duration="2000">Toast>
      <button @click="isShow = true">组件调用button>
    template>
    
    <script setup>
      import { ref } from 'vue'
      import Toast from '@/components/toast/index.vue'
      const isShow = ref(false)
    script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    我们平时都是这么用的

    但是这个组件只能在.vue组件中使用,现在我的项目中正在封装一个全局axios拦截器request.js,就没办法这么用了。

    封装api

    components/toast目录下,与index.vue同级,再新建一个index.js文件,写入以下代码:

    import { createApp } from 'vue'
    import Toast from './index.vue'
    
    const showToast = (msg, options = { duration: 1500 }) => {
      const { duration } = options
      const div = document.createElement('div')
      const componentInstance = createApp(Toast, {
        show: true,
        msg,
        duration
      })
    
      componentInstance.mount(div)
      document.body.appendChild(div)
      
      let timer = null
      clearTimeout(timer)
      timer = setTimeout(() => {
        componentInstance.unmount(div); 
        document.body.removeChild(div);
      }, duration)
    }
    
    export default showToast
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    然后就可以在任意地方调用showToast方法。

    在main.js调用

    再来看看为什么components/toast/index.js能做到这个效果

    1. vue中解构出createApp,看到这个是不是很熟悉?对,就是main.js中我们看到的那个createApp

    2. 引入写好的toast组件,传给createApp,得到一个组件实例

    3. 将组件实例挂载到一个动态创建的div元素上

    4. 将div元素追加到body元素中

    再看看main.js

    没有任何区别

  • 相关阅读:
    RocketMQ读写分离实战
    工业智能网关BL110应用之五十三: 实现西门子S7-200 PLC接入OPC UA 云平台
    面试官: AMS在Android起到什么作用,简单的分析下Android的源码
    【小程序项目开发-- 京东商城】uni-app之自定义搜索组件(中)-- 搜索建议
    流程控制知识大闯关
    windows部署java环境
    [深度学习][pytorch]pytorch实现一个简单得线性回归模型并训练
    20220912深圳市梧桐山桃花源看植物
    【操作系统】错题库
    【C#】转换8位或16位像素值为Bitmap
  • 原文地址:https://blog.csdn.net/xinTianou123/article/details/134024587