Vue组件的一些底层细节

Vue组件的本质与Vue.extend方法

ButtonCounter 确实只是一个 组件配置对象 ,而不是一个组件本身。当你将这个配置对象注册到Vue实例的 components 选项中时,Vue内部会自动调用 Vue.extend() 方法来处理这个配置对象。

Vue.extend()的作用 :

  • 它接收一个组件配置对象作为参数

  • 返回一个 VueComponent构造函数 (本质是一个函数)

  • 这个构造函数继承自Vue构造函数

当你在Vue实例中注册组件时,Vue内部会执行类似这样的操作:

javascript 复制代码
components: {
  'button-counter': Vue.extend(ButtonCounter)
}

所以注册的实际上是 Vue.extend() 返回的构造函数,而不是你原始的配置对象。

组件实例化过程

当Vue模板中遇到 <button-counter></button-counter> 标签时:

  1. Vue会使用之前通过 Vue.extend() 创建的构造函数

  2. 创建一个该构造函数的实例对象

  3. 这个实例对象与Vue实例类似,但有一些特定的组件行为

为什么组件本质是函数(构造函数)

  1. 组件的注册形式 :注册的是构造函数,这样Vue才能根据需要多次实例化组件

  2. 实例化过程 :使用 new VueComponent(options) 的方式创建组件实例

  3. 复用性考虑 :作为构造函数可以创建多个独立的组件实例

Vue实例和组件实例的关系

  • Vue实例 :通过 new Vue() 创建,是根实例

  • 组件实例 :通过 new VueComponent() 创建,是子实例

  • 继承关系 : VueComponent.prototype.proto === Vue.prototype ,所以组件实例可以访问Vue原型上的方法

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../vue.js/vue.js"></script>
</head>

<body>
    <div id="app">
        <!-- 使用组件 button-counter -->
        <button-counter></button-counter>
    </div>

    <script>
        // 定义一个名为 button-counter 的新组件,同时注册为全局组件
        const ButtonCounter = {
            data: function () {
                return {
                    count: 0
                }
            },
            template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
        }

        console.log('原始配置对象:', ButtonCounter) // 普通对象

        // 手动调用Vue.extend
        const ButtonCounterConstructor = Vue.extend(ButtonCounter)
        console.log('Vue.extend返回:', ButtonCounterConstructor) // 构造函数
        console.log('是否是函数:', typeof ButtonCounterConstructor === 'function') // true

        // 创建组件实例
        const componentInstance = new ButtonCounterConstructor()
        console.log('组件实例:', componentInstance) // 对象


        const vm = new Vue({
            el: '#app',
            data: {
                message: 'hello vue'
            },
            components: {
                'button-counter': ButtonCounter
            }
        })
        console.log(vm)
    </script>

</body>

</html>
相关推荐
程序员爱钓鱼14 分钟前
Go操作Excel实战详解:github.com/xuri/excelize/v2
前端·后端·go
子兮曰8 小时前
async/await高级模式:async迭代器、错误边界与并发控制
前端·javascript·github
恋猫de小郭9 小时前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter
GIS之路11 小时前
ArcGIS Pro 中的 Notebooks 入门
前端
IT_陈寒12 小时前
React状态管理终极对决:Redux vs Context API谁更胜一筹?
前端·人工智能·后端
lemon_yyds13 小时前
《vue 2 升级vue3 父组件 子组件 传值: value 和 v-model
vue.js
Kagol13 小时前
TinyVue 支持 Skills 啦!现在你可以让 AI 使用 TinyVue 组件搭建项目
前端·agent·ai编程
柳杉13 小时前
从零打造 AI 全球趋势监测大屏
前端·javascript·aigc
simple_lau13 小时前
Cursor配置MasterGo MCP:一键读取设计稿生成高还原度前端代码
前端·javascript·vue.js
睡不着先生13 小时前
如何设计一个真正可扩展的表单生成器?
前端·javascript·vue.js