Vue.extend

Vue.extend 是 Vue 2 中的一个重要 API,用于基于一个组件配置对象创建一个“可复用的组件构造函数”。它是 Vue 内部构建组件的底层机制之一,适用于某些高级用法,比如手动挂载组件、弹窗动态渲染等。

⚠️ 在 Vue 3 中已被移除,Vue 3 使用 defineComponent 替代组件定义方式,推荐改用 Composition API 和函数式组件模式。

🧩 Vue.extend 的基本用法

const MyComponent = Vue.extend({template: '<div>Hello {{ name }}</div>',data() {return {name: 'World'};}
});

这个 MyComponent 是一个构造函数,你可以像创建 Vue 实例一样使用它:

const vm = new MyComponent();
vm.$mount('#app'); // 或者不传参数,使用 vm.$mount() + DOM 操作手动插入

📦 使用场景举例

✅ 动态创建组件实例(如弹窗)

const Popup = Vue.extend({template: '<div class="popup">我是弹窗</div>'
});const instance = new Popup();
instance.$mount(); // 不传参数,不插入页面
document.body.appendChild(instance.$el); // 手动挂载

✅ 结合 propsData 动态传值

const Alert = Vue.extend({props: ['message'],template: '<div class="alert">{{ message }}</div>'
});const alertInstance = new Alert({propsData: {message: '操作成功'}
});
alertInstance.$mount();
document.body.appendChild(alertInstance.$el);

✅ 用于组件库或插件封装(如 Message、Toast)

很多组件库(如 Element UI)内部使用 Vue.extend 构建弹窗或消息提示组件。

🔍深入理解:Vue.extend 做了什么?

本质上:

Vue.extend(ComponentOptions)

会返回一个新的组件构造函数,该构造函数是基于你传入的选项创建的,继承自 Vue 构造器,具备 Vue 实例的能力。

相当于内部做了:

function SubComponent() {Vue.call(this); // 继承 Vue 构造器// ...
}
SubComponent.prototype = Object.create(Vue.prototype);

所以你可以这样理解:

  • Vue.extend 类似于类的继承
  • 生成的构造器可以多次 new 实例化
  • 实例是完整的 Vue 实例,具备 data、methods、watch、生命周期等功能

❗ 注意事项

问题原因
this.xxx 报错未通过 $mount 激活组件
propsData 无效只能传给 Vue.extend 的实例,而不是组件本身
内存泄漏手动创建的组件需要手动 $destroy() 和移除 DOM

🚫 Vue 3 替代方案

Vue.extend 在 Vue 3 被移除,推荐使用:

✅ defineComponent + createApp

import { createApp, defineComponent } from 'vue';const Alert = defineComponent({props: ['message'],template: '<div>{{ message }}</div>'
});const app = createApp(Alert, { message: '你好 Vue 3' });
const container = document.createElement('div');
document.body.appendChild(container);
app.mount(container);

✅ 总结

内容Vue.extend
定义方式const Ctor = Vue.extend(options)
本质返回继承自 Vue 的构造函数
常见用途弹窗、动态组件、组件库
Vue 3 替代defineComponent + createApp()

例子

Vue 2 弹窗组件的样式增强版,加入了:

  • ✅ 遮罩层(点击遮罩可关闭)
  • ✅ 居中弹出 + 阴影 + 圆角
  • ✅ 动画效果(淡入、淡出)
  • ✅ 简洁现代风格(仿 Element UI)

🗂️ 目录结构

├── index.html
├── main.js
├── MyDialog.js

📄 MyDialog.js — 定义弹窗组件

// MyDialog.js
import Vue from 'vue';const MyDialog = Vue.extend({props: ['message'],data() {return {visible: false};},mounted() {// 延迟显示以触发动画setTimeout(() => this.visible = true, 10);},methods: {close() {this.visible = false;setTimeout(() => {this.$destroy();if (this.$el && this.$el.parentNode) {this.$el.parentNode.removeChild(this.$el);}}, 300); // 延迟移除以匹配动画},onMaskClick(e) {if (e.target === this.$el) {this.close();}}},template: `<div class="dialog-mask" @click="onMaskClick"><div class="dialog-box" :class="{ 'dialog-show': visible, 'dialog-hide': !visible }"><p class="dialog-message">{{ message }}</p><button class="dialog-close" @click="close">关闭</button></div></div>`,style: `.dialog-mask {position: fixed;top: 0; left: 0;width: 100vw; height: 100vh;background: rgba(0, 0, 0, 0.4);display: flex;align-items: center;justify-content: center;z-index: 9999;}.dialog-box {background: white;border-radius: 8px;padding: 20px 24px;box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);transform: scale(0.9);opacity: 0;transition: all 0.3s ease;min-width: 300px;}.dialog-show {transform: scale(1);opacity: 1;}.dialog-hide {transform: scale(0.9);opacity: 0;}.dialog-message {font-size: 16px;margin-bottom: 16px;}.dialog-close {background-color: #409eff;border: none;color: white;padding: 8px 16px;border-radius: 4px;cursor: pointer;}.dialog-close:hover {background-color: #66b1ff;}`
});// 注入样式(确保样式在页面中)
const style = document.createElement('style');
style.textContent = MyDialog.options.style;
document.head.appendChild(style);export default MyDialog;

📄 main.js — 使用 Vue.extend 创建实例并挂载

// main.js
import Vue from 'vue';
import MyDialog from './MyDialog.js';new Vue({el: '#app',methods: {showDialog() {const DialogConstructor = MyDialog;const instance = new DialogConstructor({propsData: {message: '这是一个提示弹窗'}});instance.$mount(); // 手动挂载组件document.body.appendChild(instance.$el); // 插入到页面}},template: `<div><button @click="showDialog">打开弹窗</button></div>`
});

📄 index.html — 引入脚本

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>增强版 Vue.extend 弹窗示例</title><style>/* 弹窗遮罩层样式 */.dialog-overlay {position: fixed;top: 0;left: 0;width: 100%;height: 100%;background: rgba(0, 0, 0, 0.6);display: flex;align-items: center;justify-content: center;z-index: 1000;}/* 弹窗内容样式 */.dialog-content {background: #fff;padding: 20px;border-radius: 5px;text-align: center;min-width: 300px;box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);}/* 过渡动画 - 淡入淡出 */.dialog-fade-enter-active,.dialog-fade-leave-active {transition: opacity 0.3s;}.dialog-fade-enter,.dialog-fade-leave-to {opacity: 0;}</style>
</head>
<body><div id="app"></div><!-- Vue 2 官方 CDN --><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><!-- 使用 type="module" 加载我们的脚本 --><script type="module" src="./main.js"></script>
</body>
</html>

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

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

相关文章

【MySQL系列】SQL 分组统计与排序

博客目录 引言一、基础语法解析二、GROUP BY 的底层原理三、ORDER BY 的排序机制四、NULL 值的处理策略五、性能优化建议六、高级变体查询 引言 在现代数据分析和数据库管理中&#xff0c;分组统计是最基础也是最核心的操作之一。无论是业务报表生成、用户行为分析还是系统性能…

spring中的InstantiationAwareBeanPostProcessor接口详解

一、接口定位与核心功能 InstantiationAwareBeanPostProcessor是Spring框架中扩展Bean生命周期的关键接口&#xff0c;继承自BeanPostProcessor。它专注于Bean的实例化阶段&#xff08;对象创建和属性注入&#xff09;的干预&#xff0c;而非父接口的初始化阶段&#xff08;如…

uniapp使用sse连接后端,接收后端推过来的消息(app不支持!!)

小白终成大白 文章目录 小白终成大白前言一、什么是SSE呢&#xff1f;和websocket的异同点有什么&#xff1f;相同点不同点 二、直接上实现代码总结 前言 一般的请求就是前端发 后端回复 你一下我一下 如果需要有什么实时性的 后端可以主动告诉前端的技术 我首先会想到 webso…

QML学习06Button

QMLx学习06Button 1、Button1.1 状态改变&#xff08;checkable&#xff09;1.2 排斥性&#xff08;autoExclusive&#xff09;1.3 重复触发&#xff08;autoRepeat&#xff09;、第一次触发延时时间&#xff08;autoRepeatDelay&#xff09;、相互之间触发的时间间隔&#xff…

什么是前端工程化?它有什么意义

前端工程化是指通过工具、流程和规范,将前端开发从手工化、碎片化的模式转变为系统化、自动化和标准化的生产过程。其核心目标是 提升开发效率、保障代码质量、增强项目可维护性,并适应现代复杂 Web 应用的需求。 一、前端工程化的核心内容 1. 模块化开发 代码模块化:使用 …

校园二手交易系统

该交易平台分为两部分&#xff0c;前台和后台。用户在前台进行商品选购以及交易&#xff1b;管理员登录后台可以对商品进行维护&#xff0c;主要功能包含&#xff1a; 后台系统的主要功能模块如下&#xff1a; 登录功能、注册功能、后台首页 系统设置&#xff1a; 菜单管理、…

06-Web后端基础(java操作数据库)

1. 前言 在前面我们学习MySQL数据库时&#xff0c;都是利用图形化客户端工具(如&#xff1a;idea、datagrip)&#xff0c;来操作数据库的。 我们做为后端程序开发人员&#xff0c;通常会使用Java程序来完成对数据库的操作。Java程序操作数据库的技术呢&#xff0c;有很多啊&a…

uni-app学习笔记十三-vue3中slot插槽的使用

在页面开发中&#xff0c;通常一个页面分为头部&#xff0c;尾部&#xff0c;和中心内容区。其中头部&#xff0c;尾部一般比较固定&#xff0c;而中心区域往往是多样的&#xff0c;需要自定义开发。此时&#xff0c;我们可以引入slot(插槽)来实现这一目标。<slot> 作为一…

Agent模型微调

这篇文章讲解&#xff1a; 把 Agent 和 Fine-Tuning 的知识串起来&#xff0c;在更高的技术视角看大模型应用&#xff1b;加深对 Agent 工作原理的理解&#xff1b;加深对 Fine-Tuning 训练数据处理的理解。 1. 认识大模型 Agent 1.1 大模型 Agent 的应用场景 揭秘Agent核心…

【最新版】Arduino IDE的安装入门Demo

1、背景说明 1、本教程编写日期为2025-5-24 2、Arduino IDE的版本为&#xff1a;Arduino IDE 2.3.6 3、使用的Arduino为Arduino Uno 1、ArduinoIDE的安装 1、下载。网址如下&#xff1a;官网 2、然后一路安装即可。 期间会默认安装相关驱动&#xff0c;默认安装即可。 3、安…

Python应用运算符初解

大家好!运算符是编程中不可或缺的工具&#xff0c;它们能帮助我们执行各种计算和操作。无论是数学运算&#xff0c;还是变量赋值&#xff0c;运算符都在背后默默发挥作用。对于编程初学者来说&#xff0c;理解并掌握常见运算符的用法是迈向编程世界的重要一步。 算术运算符: 加…

小米2025年校招笔试真题手撕(二)

一、题目 给一个长度为n的序列和一个整数x&#xff0c;每次操作可以选择序列中的一个元素&#xff0c;将其从序列中删去&#xff0c;或者将其值加一。 问至少操作多少次&#xff0c;可以使操作后的序列&#xff08;可以为空&#xff09;中数字之和是x的倍数。 输入描述&#…

CNN卷积神经网络到底卷了啥?

参考视频&#xff1a;卷积神经网络&#xff08;CNN&#xff09;到底卷了啥&#xff1f;8分钟带你快速了解&#xff01; 我们知道&#xff1a; 图片是由像素点构成&#xff0c;即最终的成像效果是由背后像素的颜色数值所决定 在Excel中&#xff1a;有这样一个由数值0和1组成的66…

教师技术知识对人工智能赋能下教学效果的影响:以教学创新为中介的实证研究

教师技术知识对人工智能赋能下教学效果的影响&#xff1a;以教学创新为中介的实证研究 摘要 随着教育信息化的快速发展&#xff0c;人工智能技术在教育领域的应用日益广泛&#xff0c;为教育教学带来了深刻变革。然而&#xff0c;当前关于教师技术知识如何影响人工智能赋能下的…

Linux驱动学习笔记(九)

设备模型 1.kobject的全称为kernel object&#xff0c;即内核对象&#xff0c;每一个kobject都会对应到系统/sys/下的一个目录&#xff0c;这些目录的子目录也是一个kobject&#xff0c;以此类推&#xff0c;这些kobject构成树状关系&#xff0c;如下图&#xff1a; kobject定…

25年上半年五月之软考之设计模式

目录 一、单例模式 二、工厂模式 三、 抽象工厂模式 四、适配器模式 五、策略模式 六、装饰器模式 ​编辑 考点&#xff1a;会挖空super(coffeOpertion); 七、代理模式 为什么必须要使用代理对象&#xff1f; 和装饰器模式的区别 八、备忘录模式 一、单例模式 这个…

Python打卡第36天

浙大疏锦行 作业&#xff1a; 对之前的信贷项目&#xff0c;利用神经网络训练下&#xff0c;尝试用到目前的知识点让代码更加规范和美观。 import torch import torch.nn as nn import torch.optim as optim from sklearn.model_selection import train_test_split from sklear…

全面理解类和对象(下)

文章目录 再谈构造函数初始化列表 static概念&#xff1a; 友元友元函数友元类 内部类再次理解类和对象 再谈构造函数 class Date { public:Date(int year, int month, int day){_year year;_month month;_day day;} private:int _year;int _month;int _day; };上述代码有了…

TomatoSCI分析日记——层次聚类

TomatoSCI分析日记——层次聚类 今天介绍的是一种常见的聚类方法——层次聚类。层次聚类会将数据集划分成嵌套的簇&#xff0c;形成一个层次结构&#xff08;树状图&#xff09;&#xff0c;经常用于探究样本的相似性。用大白话来说&#xff0c;就是&#xff1a;我有一大堆样品…

mysql都有哪些锁?

MySQL中的锁机制是确保数据库并发操作正确性和一致性的重要组成部分&#xff0c;根据锁的粒度、用途和特性&#xff0c;可以分为多种类型。以下是MySQL中常见的锁及其详细说明&#xff1a; 一、按锁的粒度划分 行级锁&#xff08;Row-level Locks&#xff09; 描述&#xff1a;…