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日

相关文章

  • 【hyperscan】编译hyperscan 4.0.0

    【hyperscan】编译hyperscan 4.0.0 在编写高效的网络安全应用程序时,使用快速而精确的模式匹配算法是非常重要的。Hyperscan是一款支持使用正则表达式进行高性能扫描的工具包,可以在包括x86、x64和ARM在内的多种平台上运行。在本文中,我们将介绍如何编译最新版本的Hyperscan(4.0.0)。 准备工作 在开始编译之前,需要进行…

    其他 2023年3月28日
    00
  • 听说看了这篇文章就彻底搞懂了什么是OPC(上)

    听说看了这篇文章就彻底搞懂了什么是OPC(上) OPC是什么? OPC全称为”OLE for Process Control”,即面向过程控制的OLE。简单来说,它是一种应用程序编程接口,用于实现不同厂家的设备和系统之间的互联互通,使它们能够在同一平台上进行数据交换和共享。OPC可以联接不同的硬件,例如传感器、运动控制设备和PLC(可编程逻辑控制器)等自动化…

    其他 2023年3月28日
    00
  • JavaScript实现大整数减法

    JavaScript实现大整数减法的完整攻略 本文将为您提供一份完整攻略,介绍如何使用JavaScript实现大整数减法,并提供两个示例说明。 实现思路 大整数减法的实现思路与大整数加法类似,只需要将减数取相反数,然后使用大整数加法即可。具体步骤如下: 判断被减数和减数的符号,如果不同,则将减数取相反数,然后使用大整数加法。 将被减数和减数转换为数组,并将数…

    other 2023年5月5日
    00
  • 人脸识别-论文阅读-arcface及其由来(sphereface、cosface)

    人脸识别-论文阅读-arcface及其由来(sphereface、cosface)攻略 1. 了解人脸识别算法 人脸识别是计算机视觉领域的一个重要研究方向。在人脸识别中,人脸特征提取是关键的步骤。深度学习是当前人脸识别领域的主流方法,其中基于深度学习的人脸识别算法可以分为两类:基于特征提取的方法和基于度量学习的方法。基于特征提取的方法将人脸图像映射到一个低维…

    other 2023年5月7日
    00
  • vue项目中应用ueditor自定义上传按钮功能

    下面详细讲解“vue项目中应用ueditor自定义上传按钮功能”的完整攻略。 一、准备工作 1. 安装ueditor 在vue项目中引入并使用ueditor需要先下载ueditor。可以下载最新的stable版本,也可以到github上下载最新的development版本。 下载后将ueditor文件夹拷贝到项目中的静态资源文件夹中,例如,拷贝到public…

    other 2023年6月25日
    00
  • C++中vector容器使用详细说明

    C++中vector容器使用详细说明 1. 简介 vector是一个类似于动态数组的容器,能够存储任意类型的数据,提供了访问和遍历元素的方法。与数组不同的是,vector的大小可以动态变化,可以随时添加或删除元素。vector是标准模板库(STL)的一部分,因此可以与其他STL容器,例如list、map和set一起使用。 2. 基本使用 2.1 vector…

    other 2023年6月26日
    00
  • c#与java中byte字节的区别及转换方法

    C#与Java中byte字节的区别及转换方法 介绍 在C#和Java编程中,byte是基本的数据类型,它表示的是8位的二进制数据。尽管两种编程语言有相似的语法和处理方式,但它们之间仍然存在一些不同。本文将介绍C#和Java中byte类型之间的区别,以及在它们之间的转换方法。 C#和Java中byte类型的区别 值范围 C#中的byte类型的取值范围是从0到2…

    其他 2023年3月28日
    00
  • python2.7和python3的主要区别

    简介 Python是一种高级编程语言,有多个版本。Python 2.7和Python 3是两个主要版本。虽然它们都是Python语言,但它之间有一些重要的别。本攻略将详细讲解Python 2.7和Python 3的要区别。 区别 下是Python 2.7Python 3的主要区别: print语句:在Python 2.7中,print是一个语句,在Pytho…

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