vue3手动封装弹出框组件message的方法

下面是针对“vue3手动封装弹出框组件message的方法”的完整攻略:

1. 前置知识

在封装message组件之前,需要掌握Vue3的以下知识点:

  1. 使用Vue3的Composition API编写组件
  2. 如何在Vue3中进行全局组件注册
  3. 如何在Vue3的setup函数中使用provide和inject来进行父子组件之间的通信

2. 开始封装message组件

首先,我们需要在Vue3的官方文档中寻找message组件源码并进行分析,以此为基础来进行我们的封装。

<template>
  <div class="el-message"></div>
</template>

<script>
import { ref, watchEffect, computed, onMounted, onBeforeUnmount } from 'vue'
import { ElMessageOptions, MessageType, MESSAGE_TYPES, SEVERITY_TYPES } from './types'

const baseClass = 'el-message'

export default {
  name: 'ElMessage',
  setup() {
    const messages = ref<ElMessageOptions[]>([])

    const removeMessage = (msg: ElMessageOptions) => {
      const idx = messages.value.indexOf(msg)
      if (idx > -1) {
        messages.value.splice(idx, 1)
      }
    }

    const addMessage = (msg: ElMessageOptions) => {
      messages.value.push(msg)

      if (msg.duration > 0) {
        setTimeout(() => {
          removeMessage(msg)
        }, msg.duration)
      }
    }

    const close = (msg: ElMessageOptions) => {
      removeMessage(msg)
    }

    const getMessageClasses = (msg: ElMessageOptions) => {
      const result: string[] = []

      if (msg.type) {
        const typeClass = `el-message-${msg.type}`
        if (MESSAGE_TYPES.includes(msg.type)) {
          result.push(typeClass)
        } else {
          console.error(`[ElMessage] Invalid message type ${msg.type}`)
        }
      }

      if (msg.severity) {
        const severityClass = `el-message-severity-${msg.severity}`
        if (SEVERITY_TYPES.includes(msg.severity)) {
          result.push(severityClass)
        } else {
          console.error(`[ElMessage] Invalid message severity ${msg.severity}`)
        }
      }

      return result
    }

    const getIconClass = (msg: ElMessageOptions) => {
      if (msg.type === MessageType.Success) {
        return 'el-icon-success'
      } else if (msg.type === MessageType.Warning) {
        return 'el-icon-warning'
      } else if (msg.type === MessageType.Error) {
        return 'el-icon-error'
      } else if (msg.type === MessageType.Info) {
        return 'el-icon-info'
      } else {
        return ''
      }
    }

    const getMsgsWithComputedValues = computed(() => {
      return messages.value.map(msg => {
        return {
          ...msg,
          classes: getMessageClasses(msg),
          iconClass: getIconClass(msg)
        }
      })
    })

    const handleOptionMessage = (option: string) => {
      addMessage({
        message: option,
        duration: 3000,
        type: MessageType.Info
      })
    }

    watchEffect((onInvalidate) => {
      const register = (func: (msg: string) => void) => {
        onInvalidate(() => {
          ipcRenderer.removeListener('el-message', func)
        })
        ipcRenderer.on('el-message', func)
      }

      // register ipc listener
      const handler = (event: any, arg: any) => {
        if (arg.type === 'el-message') {
          const msg = arg.payload
          addMessage(msg)
        }
      }
      register(handler)

      return () => {
        ipcRenderer.removeListener('el-message', handler)
      }
    })

    onMounted(() => {
      window.$message = handleOptionMessage
    })

    onBeforeUnmount(() => {
      window.$message = null
    })

    return {
      messages: getMsgsWithComputedValues,
      close
    }
  }
}
</script>

从上面的源码中,我们可以看到,message组件的主要功能是:接收消息、展示消息、定时移除消息。因此,我们需要在自己封装的组件中也实现这几个功能。

2.1 父组件向子组件传递数据

在Vue3中,父组件可以使用provide来向子组件传递数据,而子组件可以使用inject来接收数据。这种方式在传递状态管理库如Vuex中的store实例时尤其常用。

例如,在父组件中,我们可以这样定义provide:

import { provide } from 'vue'

export default {
  setup() {
    provide('message', this.$message) // 传递message方法给子组件
  }
}

然后,在我们封装的message组件中,就可以这样来使用inject来接收message方法:

import { inject } from 'vue'

export default {
  setup() {
    const message = inject('message')

    // 使用message方法展示弹窗
    message({
      type: MessageType.Info,
      message: 'Hello World',
      duration: 3000
    })
  }
}

为了方便起见,我们把message方法直接传递给window全局变量,这样在使用的时候就可以直接调用window.$message方法来展示弹窗了。

2.2 编写弹出框组件

知道了如何父组件向子组件传递数据后,我们就可以编写我们自己的弹出框组件了。我们要实现的功能是:弹出框显示到页面上并在指定时间后自动消失。

<template>
  <div class="my-message" :class="isShow ? 'show' : ''">
    {{ message }}
  </div>
</template>

<script>
export default {
  props: {
    message: {
      type: String,
      required: true
    },
    duration: {
      type: Number,
      default: 3000 // 默认展示时间为3秒钟
    }
  },
  data() {
    return {
      isShow: false
    }
  },
  mounted() {
    this.isShow = true
    setTimeout(() => {
      this.isShow = false
    }, this.duration)
  }
}
</script>

<style scoped>
.my-message {
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  padding: 16px;
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  transition: all 0.3s;
  opacity: 0;
  z-index: 1000
}
.my-message.show {
  opacity: 1;
}
</style>

按照上面的代码来编写自己的弹出框组件,然后再在全局组件注册中注册它,这样就可以在任意位置使用自己的message方法来展示弹框了。

示例1:定义一个包含message和duration参数的message方法

import { createApp } from 'vue'
import App from './App.vue'

import Message from './components/Message.vue'

const app = createApp(App)

app.component('my-message', Message)

app.config.globalProperties.$message = function(message, duration = 3000) {
  const mountNode = document.createElement('div')
  document.body.appendChild(mountNode)

  const close = () => {
    app.unmount(mountNode)
    setTimeout(() => {
      document.body.removeChild(mountNode)
    }, 300)
  }

  const props = {
    message,
    duration
  }

  const vm = app.mount(mountNode, {
    template: `<my-message v-bind="$props" />`,
    setup() {
      return {
        props
      }
    }
  })

  setTimeout(close, duration)
}

这样,我们就可以在任意的Vue3组件中使用window.$message方法来展示弹出框了,例如:

<template>
  <div>
    <button @click="handleMessageClick">点击展示信息</button>
  </div>
</template>

<script>
export default {
  setup() {
    const handleMessageClick = () => {
      window.$message('Hello World', 3000)
    }

    return {
      handleMessageClick
    }
  }
}
</script>

示例2:在组件中使用message方法

<template>
  <button @click="handleClick">点击展示信息</button>
</template>

<script>
import { onMounted, onBeforeUnmount } from 'vue'
import { inject } from 'vue'

export default {
  setup() {
    const message = inject('message')
    const duration = 3000

    const handleClick = () => {
      message('Hello World', duration)
    }

    return {
      handleClick
    }
  }
}
</script>

通过上面的代码,我们就可以在任意Vue3组件中使用我们自己定义的message方法来展示弹出框了,不再局限于在全局使用Vue2的组件。同时,由于我们的自定义组件也符合Vue3的规范,因此在更改项目为Vue3之后,我们无需再做额外的兼容性修改。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue3手动封装弹出框组件message的方法 - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • c#usercontrol用法

    C# UserControl用法 UserControl是C#中常用的控件之一,它可以用于创建自定义的用户界面。本文将详细讲解C# UserControl的用法,包括创建、使用和常见问题的解决方法。 创建UserControl 创建UserControl的步骤如下: 在Visual Studio中创建一个新的Windows Forms应用程序。 解决方案资源…

    other 2023年5月7日
    00
  • 浅谈VC中预编译的头文件放那里的问题分析

    我很乐意为大家提供有关“浅谈VC中预编译的头文件放那里的问题分析”的完整攻略。首先,我们需要明确,预编译头文件(Precompiled Header,PCH)是一种提高编译速度和性能的技术,将头文件预编译成一个二进制文件,并在后续编译过程中重复使用,而不是每次都重新编译头文件。那么,在VC中,预编译头文件应该放在哪里呢? 一般来说,VC的预编译头文件应该放在…

    other 2023年6月27日
    00
  • 别墅无线WiFi覆盖解决方案

    以下是“别墅无线WiFi覆盖解决方案”的完整攻略。 确定需求 在开始部署无线网络之前,首先需要明确别墅无线WiFi覆盖的需求。比如需要覆盖的面积、设备数量、无线速率要求等等。只有确定了需求,才能针对性的选择设备,并进行合理布局。例如,假设一个别墅共有三层,面积300平方米,需要支持10台以上的设备同时连接,而且需要稳定的高速无线网络。 设备选购 根据需求,需…

    other 2023年6月26日
    00
  • jQuery实现预加载图片的方法

    jQuery实现预加载图片的方法 在需要展示大量图片的网站应用中,为了提升用户的体验,我们通常需要预加载图片。预加载图片是指在页面显示前将需要展示的图片提前加载,当用户实际需要访问时,能够更快地展现出来。本文将介绍使用jQuery来实现预加载图片的方法。 使用$.Deferred()对象实现 $.Deferred()对象是jQuery中的一个异步处理工具,我…

    other 2023年6月25日
    00
  • 苹果iOS 13.3/iPadOS 13.3开发者预览版Beta2推送 iOS13.3 beta2更新内容汇总

    苹果iOS 13.3/iPadOS 13.3开发者预览版Beta2推送 iOS13.3 beta2更新内容汇总 简介 本次推送的是苹果iOS 13.3/iPadOS 13.3开发者预览版Beta2,是一次针对开发者的测试版本。本文将对iOS13.3 beta2的更新内容和使用方法进行详细的介绍。 更新内容 修复了iCloud Backup的问题 在iOS 1…

    other 2023年6月26日
    00
  • 使用脚本实现故障时自动重启Apache

    使用脚本实现故障时自动重启Apache是一项非常重要的工作,本文将介绍如何创建一个可靠的脚本来检测Apache服务状态,并在服务故障时自动重启它。具体步骤如下: 1.创建一个监控脚本 创建一个脚本文件(如monitor_apache.sh),用于检测Apache服务是否运行。在脚本中使用curl命令检测服务是否可以访问,如果访问失败,则将Apache服务重启…

    other 2023年6月27日
    00
  • Win7系统修改文件格式(后辍)设置方法图文教程

    Win7系统修改文件格式(后缀)设置方法图文教程 在Win7系统中,修改文件格式(后缀)是一项常见的操作。通过修改文件的后缀,我们可以改变文件的类型,使其能够被不同的程序打开。下面是详细的操作步骤: 步骤一:显示文件后缀名 打开“资源管理器”(可以通过桌面上的“计算机”图标或者任务栏上的文件夹图标打开)。 在资源管理器的顶部菜单栏中,点击“查看”选项卡。 在…

    other 2023年8月5日
    00
  • vue 如何使用递归组件

    使用递归组件是 Vue 中非常重要的一种技巧,可以处理许多常见的应用程序和数据结构问题,如树形结构的渲染、评论区嵌套等。 在 Vue 中,我们可以通过一个组件调用自身来实现递归的效果。使用递归组件的一般步骤如下: 创建递归组件的基础组件,并指定一个唯一的名称。 在组件模板中,使用自身名称调用自身组件。 为组件提供一个终止条件,以避免创建无限递归。 下面我们通…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部