Vue2函数式组件实战:手写可调用的动态组件,适用于toast轻提示、tip提示、dialog弹窗等

news2025/4/3 18:41:30

Vue2函数式组件实战:手写可调用的动态组件

在这里插入图片描述

一、需求场景分析

在开发中常遇到需要动态调用的组件场景:

  • 全局弹窗提示
  • 即时消息通知
  • 动态表单验证
  • 需要脱离当前DOM树的悬浮组件

传统组件调用方式的痛点:必须预先写入模板,可能还要用ref绑定组件

<template>
  <!-- 必须预先写入模板 -->
  <MyComponent v-if="show" :content="text"/>
</template>

二、函数式组件实现方案

//myComponent.js
import MyComponent from './MyComponent.vue';
import Vue from 'vue';

let instance;

//实例初始化
function initInstance(){
    //先销毁已有实例,单例模式
    if(instance){
        instance.$destroy();
        // 显式移除DOM
        instance.$el.parentNode.removeChild(instance.$el) 
    }
    instance = new (Vue.extend(MyComponent))({
        el: document.createElement('div')
    });

    //自定义事件,控制组件显隐
    instance.$on('show',value=>{
        instance.value = value
    })
}

//函数式组件调用
function myComponent(options){
    if(!instance){
        initInstance();
    }
    //复制传参并控制显示组件
    Vue.nextTick(() => {
        Object.keys(options).forEach(key => {
            instance[key] = options[key]
        })
        instance.value = true
    })
}

myComponent.Component = MyComponent;
export default myComponent;
<template>
  <transition name="fade">
    <div v-show="value" class="component-wrapper">
      <div class="header">
        <slot name="header">{{ title }}</slot>
      </div>
      <div class="content">
        {{ content }}
      </div>
      <div class="footer">
        <button @click="handleClose">关闭</button>
      </div>
    </div>
  </transition>
</template>

<script>
export default {
  props: {
    content: String,
    title: {
      type: String,
      default: '提示'
    }
  },
  mounted() {
    // 智能挂载到最近的dialog-container
    const container = document.querySelector('.dialog-container') || document.body
    container.appendChild(this.$el)
  },
  methods: {
    handleClose() {
            this.$emit('show',false);
    }
  },
  beforeDestroy() {
    // 安全移除DOM
    if (this.$el.parentNode) {
      this.$el.parentNode.removeChild(this.$el)
    }
  }
}
</script>

<style scoped>
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.3s;
}
.fade-enter, .fade-leave-to {
  opacity: 0;
}
</style>

三、综合分析

使用方式对比

传统组件调用

<template>
  <button @click="show = true">打开</button>
  <MyComponent v-if="show" @close="show = false"/>
</template>

<script>
export default {
  data: () => ({
    show: false
  })
}
</script>

函数式组件调用

import { myComponent} from '@/utils/myComponent'

// 任意位置调用
showComponent({
  content: '操作成功',
  title: '系统提示',
})

弹窗需要考虑的问题

  1. 当页面滚动时,弹窗是否需要滚动?是否会被其他元素遮挡
  2. 移动端如何避免点击穿透问题
  3. 当频繁触发弹窗时,如何确保弹窗的内容/显隐时间正常

进阶优化建议

  1. 多实例支持
function createInstance() {
  return new (Vue.extend(MyComponent))({
    el: document.createElement('div')
  })
}

export function showComponent(options) {
  const instance = createInstance()
  // 单独管理实例
}
  1. 如果是vue3定制函数式组件,可以使用teleport将组件传送至最外层

函数式组件是Vue2中实现命令式调用的利器,但需要特别注意实例管理和DOM操作。建议仅在确实需要动态调用的场景使用,常规需求优先使用标准组件化方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2327401.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大象如何学会太空漫步?美的:科技领先、To B和全球化

中国企业正处在转型的十字路口。一边是全新的技术、全新的市场机遇&#xff1b;一边是转型要面临的沉重负累和巨大投入&#xff0c;无数中国制造、中国品牌仍在寻路&#xff0c;而有的人已经走至半途。 近日&#xff0c;美的集团交出了一份十分亮眼的2024年财报。数据显示&…

已经使用中的clickhouse更改数据目录

在更换的目录操作&#xff0c;这里更换的目录为home目录&#xff0c;原先安装的目录在/soft/clickhouse/ ,在该目录下有data目录和log目录 更改前目录 更改后目录 1、停止clickhouse服务 sudo systemctl stop clickhouse-server 2、在home目录创建clickhouse目录,在clickho…

PHP的相关配置和优化

进入etc下面 去掉注释 pid run/php-fpm.pid #指定pid文件存放位置 生成一下子配置文件 这些都是生成的fastcgi的配置文件 进入php中&#xff0c;然后复制模版&#xff0c;生成配置文件 然后编辑文件更改时区 改完之后可以生成启动脚本 这时候刷新之后&#xff0c;再启动会报…

【leetcode100】每日温度

1、题目描述 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;请在该位置用 0 来代替。 示例 1: 输…

<贪心算法>

前言&#xff1a;在主包还没有接触算法的时候&#xff0c;就常听人提起“贪心”&#xff0c;当时是layman&#xff0c;根本不知道说的是什么&#xff0c;以为很难呢&#xff0c;但去了解一下&#xff0c;发现也不过如此嘛&#xff08;bushi)&#xff0c;还以为是什么高级东西呢…

基于银河麒麟桌面服务器操作系统的 DeepSeek本地化部署方法【详细自用版】

一、3种方式使用DeepSeek 1.本地部署 服务器操作系统环境进行,具体流程如下(桌面环境步骤相同): 本例所使用银河麒麟高级服务器操作系统版本信息: (1)安装ollama 方式一:按照ollama官网的下载指南,执行如下命令: curl -fsSL https://ollama.com/install.sh | sh方…

「2025最新版React+Ant Design+Router+TailwindCss全栈攻略:从零到实战,打造高颜值企业级应用

一站式掌握最新技术栈&#xff01;手把手教你配置路由、集成UI组件库、高效开发秘籍大公开 ReactAntrouteraxiosmocktailwind css等组合安装使用教程 官网&#xff1a;React Native 中文网 使用React来编写原生应用的框架 一&#xff0c;安装 npx create-react-app my-app …

Ubuntu 24.04.2 LTS 系统安装python,创建虚拟环境

在 Ubuntu 24.04.2 LTS 系统中&#xff0c;系统本身自带了 Python 3&#xff0c;不过你还是可以按照下面的步骤来安装和配置 Python 环境。 1. 检查系统自带的 Python 版本 在终端中输入以下命令查看系统自带的 Python 版本&#xff1a; python3 --version如果显示了 Python…

redis7.0搭建redis-cluster集群部署实战

环境 基于3台centos服务 host节点1端口节点2端口master70007001slave170007001slave270007001 安装redis&#xff0c;以及环境准备 安装可以参考https://blog.csdn.net/tao1992/article/details/132614567 安装路径设置了/usr/local/redis 分别在3台服务器上执行 #配置文…

CMake学习--如何在CMake中编译静态库、动态库并在主程序中调用

目录 一、背景知识二、使用方法&#xff08;一&#xff09;编译静态库&#xff08;二&#xff09;编译动态库&#xff08;三&#xff09;在主程序中调用库 三、总结 一、背景知识 在C/C开发中&#xff0c;库&#xff08;Library&#xff09;是预先编译好的代码集合&#xff0c…

安美数字酒店宽带运营系统存在SQL注入漏洞

免责声明&#xff1a;本号提供的网络安全信息仅供参考&#xff0c;不构成专业建议。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权&#xff0c;请及时与我联系&#xff0c;我将尽快处理并删除相关内容。 漏洞描述 安美数字酒店宽带运营系统的lang…

ubuntu18 server版花屏问题

新搞了一台dellT150的塔式服务器&#xff0c;装的ubuntu18 server版。 开机后遇到花屏&#xff0c;或者卡在开机界面的问题&#xff0c;和售后技术沟通这个情况是ubuntu自带的显卡驱动包兼容问题。需要做如下设置&#xff1a; 解决&#xff1a; 1.开机&#xff0c;连续按下e…

基于神经网络的肾脏疾病预测模型

构建一个基于神经网络的肾脏疾病预测模型 1. 数据预处理 ​加载数据&#xff1a;读取 kidney_disease.csv 文件&#xff0c;加载患者医疗数据。​删除冗余特征&#xff1a;移除与预测目标无关的列&#xff08;如 al, su 等&#xff09;&#xff0c;保留关键特征&#xff08;如…

I/O多路复用 + Reactor和Proactor + 一致性哈希

网络系统 1. I/O多路复用1&#xff09;原始Socket模型通信方式2&#xff09;多进程模型3&#xff09;多线程模型4&#xff09;I/O多路复用select/pollepoll边缘触发和水平触发 2. Reactor和Proactor1&#xff09;Reactor模式2&#xff09;Reactor模式四种方案3&#xff09;单Re…

解决小程序video控件在真机和上线后黑屏不播放问题

小程序上线后&#xff0c;mp4格式的视频无法点击是黑屏&#xff0c;但是测试得时候在微信开发者工具中能够打开正常播放 原因&#xff1a;编码格式不能是vp9 微信开发者工具本地设置中把这个打开勾选。 排查&#xff1a;可以换一个视频尝试能不能真机播放&#xff0c;如果能&a…

java项目分享-分布式电商项目附软件链接

今天来分享一下github上最热门的开源电商项目安装部署&#xff0c;star 12.2k&#xff0c;自行安装部署历时两天&#xff0c;看了这篇文章快的话半天搞定&#xff01;该踩的坑都踩完了&#xff0c;软件也打包好了就差喂嘴里。 项目简介 mall-swarm是一套微服务商城系统&#xf…

【LVS】负载均衡群集部署(DR模式)

部署前IP分配 DR服务器&#xff1a;192.168.166.101 vip&#xff1a;192.168.166.100 Web服务器1&#xff1a;192.168.166.104 vip&#xff1a;192.168.166.100 Web服务器2&#xff1a;192.168.166.107 vip&#xff1a;192.168.166.100 NFS服务器&#xff1a;192.168.166.108 …

链表的操作-反转链表

链表 160相交链表 代码 class Solution { public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {ListNode* h1headA;ListNode* h2headB;while(h1&&h2){if(h1!h2){h1h1->next;h2h2->next;}else{return h1;}}if(h1nullptr){h1headB;}else{h…

Linux安装Cmake (Centos 7.9)

cmake安装 这个虽然已经更新到了4.0.0版本了&#xff0c;但是我们要用3.5版本的&#xff0c;因为这个比较稳定 官方地址&#xff1a;https://github.com/Kitware/CMake/releases/tag/v3.5.0&#xff0c;选择那个cmake-3.5.0-Linux-x86_64.tar.gz下载&#xff0c; 首先解压文…

Node.js v22.14.0 多平台安装指南:Windows、Linux 和 macOS 详细教程

Node.js作为现代Web开发的基石&#xff0c;持续为开发者带来性能提升和新特性支持。本文将详细介绍在Windows、macOS和Linux系统上安装最新Node.js的多种方法&#xff0c;助您快速搭建高效的JavaScript开发环境。 &#x1f4e6; 当前最新版本 截至2025年4月&#xff0c;Node.…