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日

相关文章

  • 腾讯视频怎么切换账号?腾讯视频切换账号登录教程

    当你需要切换腾讯视频账号时,可以按照以下步骤进行: 步骤1:打开腾讯视频官网 首先,打开腾讯视频官网(https://v.qq.com/),在打开的页面上方找到“登录”按钮,点击进入登录页面。 步骤2:进入账号切换页面 在登录页面中,先输入当前登录账号的用户名和密码,然后点击“登录”按钮。登录成功后,页面会跳转到腾讯视频的主界面上。接下来,在主界面左上方找到…

    other 2023年6月27日
    00
  • 详解Linux系统无法上网解决方案

    针对“详解Linux系统无法上网解决方案”的完整攻略,我将分为以下几步来详细讲解: 1. 检查网络连接状态 首先,我们需要检查网络连接状态,确定是否已经连接上了网络。可以在终端中运行以下命令: ping www.baidu.com 如果能够正常 ping 通百度的服务器,就说明网络连接正常。如果无法 ping 通,说明存在网络连接问题,此时需要进一步排查。 …

    other 2023年6月26日
    00
  • Bootstrap布局之栅格系统学习笔记

    Bootstrap布局之栅格系统学习笔记 什么是栅格系统? 栅格系统是Bootstrap框架中的一个重要组成部分,用于创建响应式的网页布局。它将页面水平划分为12个等宽的列,开发者可以根据需要将内容放置在这些列中,从而实现灵活的布局。 栅格系统的基本结构 栅格系统由行(row)和列(column)组成。行用于包含列,而列则用于放置内容。以下是栅格系统的基本结…

    other 2023年7月28日
    00
  • Java Boolean 初始化方式详解

    Java Boolean 初始化方式详解 在Java中,Boolean类型是一种简单的数据类型,其值只有true和false两种,但它的初始化方式有多种。本文将详细讨论Boolean类型的初始化方式。 直接赋值 Boolean类型可以直接赋值为true或false,如下所示: Boolean flag = true; Boolean result = fal…

    other 2023年6月20日
    00
  • PHP 显示客户端IP与服务器IP的代码

    要显示客户端IP和服务器IP的代码,首先需要用PHP获取IP地址。使用PHP可以通过$_SERVER[‘REMOTE_ADDR’]来获取客户端IP地址,而使用$_SERVER[‘SERVER_ADDR’]可以获取服务器IP地址。以下是获取客户端和服务器IP地址的示例代码: <?php // 获取客户端IP地址 $client_ip = $_SERVER…

    other 2023年6月27日
    00
  • windows server2008R2 64位 配置 mysql-8.0.15-winx64

    Windows Server2008R2 64位 配置 mysql-8.0.15-winx64 如果你是一位网站管理员,那么你一定需要一个数据库来存储你网站的数据。 MySQL 是一个强大的开源数据库管理系统,它被广泛应用于各种网站和应用程序。本篇文章将向你介绍如何在 Windows Server2008 R2 64位系统上配置 MySQL 8.0.15。 …

    其他 2023年3月28日
    00
  • CentOS7.5 安装MySql的教程

    CentOS7.5 安装MySql的教程 环境准备 在安装Mysql之前,我们需要先确保以下条件已经满足: CentOS7.5系统已经安装完成。 系统已经启用网络,并且能够正常访问网络。 系统已经更新到最新版本。 安装Mysql 在终端中输入以下命令,以更新系统包: yum update 接下来,我们需要添加Mysql仓库,在终端中输入以下命令: rpm -…

    other 2023年6月27日
    00
  • java-如何用stringutils.equals替换所有string.equals

    以下是“Java中如何用StringUtils.equals替换所有String.equals”的完整攻略: Java中使用StringUtils.equals替换所有String.equals 在Java中,我们经常需要比较两个字符串是否相等。通常情况下,我们使用String.equals方法来比较。但是,如果我们需要比较多个字符串,使用String.eq…

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