Vue3全局组件注册的实现代码

 更新时间:2023年12月22日 09:21:55   作者:田八  
在这篇文章中,我们将学习一下 Vue3 的全局组件注册是如何实现的,文中通过代码示例给大家介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下

1. 全局组件注册

组件注册在Vue的官方文档中有详细的介绍,我们可以通过app.component方法来注册一个全局组件,如下所示:

import { createApp } from 'vue'

const app = createApp({})
app.component('component-a', {
  /* ... */
})

注册组件在Vue中是非常简单的一个操作,但是在Vue3中,我们需要知道的是,Vue3是如何将我们注册的组件挂载到app实例上的呢?

参考链接

2. 全局组件注册实现

我们可以在组件注册的代码上面打上断点,在浏览器中执行一下,然后我们就可以看到Vue3是如何将我们注册的组件挂载到app实例上的了。

当我们跟踪进入component方法中,可以看到源码实现很少,如下所示:

function component(name, component) {
    {
        // 1. 校验组件名称是否合法
        validateComponentName(name, context.config);
    }
    
    // 2. 如果没有传递组件,则返回已经注册的组件
    if (!component) {
        return context.components[name];
    }
    
    // 3. 如果传递了组件,并且组件已经注册,则打印警告信息提示组件已经注册
    if (context.components[name]) {
        warn(`Component "${name}" has already been registered in target app.`);
    }
    
    // 4. 将组件直接赋值给 app 实例的 components 属性中
    context.components[name] = component;
    
    // 5. 返回 app 实例
    return app;
}

组件注册整体来说是非常简单的一个操作,我们可以看到,Vue3在注册组件的时候,主要做了以下几件事情:

  • 校验组件名称是否合法
  • 如果没有传递组件,则返回已经注册的组件,这一步对应着已注册组件的获取
  • 如果传递了组件,并且组件已经注册,则打印警告信息提示组件已经注册,这里少提示了一个警告信息,就是会将已注册的组件覆盖
  • 将组件直接赋值给 app 实例的 components 属性中,这里只是缓存下来,并不会使用
  • 返回 app 实例,这里返回 app 实例主要是用于链式调用

3. 组件名称规则

Vue的风格指南中有明确的组件名称规则,而在组件注册的第一步也是校验组件名称是否合法,那么我们就来看一下Vue的组件名称规则。

我们可以继续跟随源码来查看validateComponentName方法的实现,如下所示:

function validateComponentName(name, config) {
    // 1. 获取内部配置的 isNativeTag 方法来判断是否是 HTML 原生标签
    const appIsNativeTag = config.isNativeTag || NO;
    
    // 2. 判断组件名是否是内置的标签名或者是原生标签名
    if (isBuiltInTag(name) || appIsNativeTag(name)) {
        // 3. 如果是内置的标签名或者是原生标签名,则打印警告信息
        warn(
            "Do not use built-in or reserved HTML elements as component id: " + name
        );
    }
}

我们可以看到,Vue的组件名称规则主要是校验组件名称是否是内置的标签名或者是原生标签名,如果是,则会打印警告信息。

isNativeTag的配置在官网中并没有明确的说明,我们可以继续跟踪源码来查看isNativeTag的实现,如下所示:

function injectNativeTagCheck(app) {
  Object.defineProperty(app.config, "isNativeTag", {
    value: (tag) => isHTMLTag(tag) || isSVGTag(tag),
    writable: false
  });
}

它是通过Object.defineProperty方法来定义的,并且writablefalse表示不可修改,我们可以看到,isNativeTag的实现是通过isHTMLTagisSVGTag来判断的;

这里就没有必要在继续看了,反正我们熟知的div/span/button等等html标签肯定是不行的,然后就是svg/path/group等等svg标签也是不行的,这里就不一一列举了。

再就是isBuiltInTag他是通过makeMap方法来实现的。

const isBuiltInTag = /* @__PURE__ */ makeMap("slot,component");

这里只有两个组件,一个是slot,一个是component,不知道为什么不包含transition,这里就不深究了。

风格指南参考链接:

Vue3 的风格指南对比 Vue2 的风格指南少了很多,但是核心理念还是一致的,所以我们可以参考 Vue2 的风格指南来学习 Vue3 的风格指南。

4. 组件挂载

在我们之前的章节中也讲过组件的挂载,但是那个讲的是一个组件是如何挂载到页面上的,并没有涉及到组件是如何从实例中获取的,这次我们就来看一下组件是如何从实例中获取的。

根据我们之前学习的章节,我们知道一个组件最后会通过createVNode方法来创建一个虚拟节点,然后通过render方法来渲染到页面上;

而虚拟节点上会有一个type属性和一个shapeFlag属性,type属性就是我们的组件,shapeFlag属性就是一个标识,用于标识当前节点的类型。

而我们的组件最后在Vue的内部都是以对象的型式存在,所以shapeFlag的值通常是4,表示是一个对象,所以最后会执行到mountComponent方法中;

这里的组件是直接通过生成子树,然后将子树进行patch的方式来挂载的,本质上是和普通的元素挂载是一样的;

由于这一块我们是用模板语法来进行组件的使用的,这里的逻辑会比较复杂,在上面的组件挂载的文章中不能完全体现, 模板本质是一个字符串,最后会转换成一个ast之后进行组件的匹配和挂载,内容量会比较大,所以会在下一章进行详细分析;

5. 总结

在这篇文章中,我们学习了Vue3的全局组件注册是如何实现的,主要是通过app.component方法来实现的,component方法内部实现很简单,主要有两个功能:

  • 注册组件,但是组件只是以对象的方式缓存在app实例的components属性中,并没有使用;
  • 获取已经注册的组件,如果没有传递组件,则通过组件名称获取已经注册的组件,这一步就是一个函数重载;

而组件挂载的过程和普通元素的挂载是一样的,都是通过patch的方式来进行的,这里就不再赘述了。

以上就是Vue3全局组件注册的实现代码的详细内容,更多关于Vue3全局组件注册的资料请关注脚本之家其它相关文章!

相关文章

  • vue 使用localstorage实现面包屑的操作

    vue 使用localstorage实现面包屑的操作

    这篇文章主要介绍了vue 使用localstorage实现面包屑的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • 浅谈使用mpvue开发小程序需要注意和了解的知识点

    浅谈使用mpvue开发小程序需要注意和了解的知识点

    这篇文章主要介绍了浅谈使用mpvue开发小程序需要注意和了解的知识点,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • Vue3中的onMounted详解与使用方法详解

    Vue3中的onMounted详解与使用方法详解

    这篇文章主要介绍了Vue3中的onMounted生命周期钩子,它在组件挂载到DOM后执行代码,onMounted只调用一次,适合进行异步操作、DOM操作和事件监听,在使用时需要注意组件销毁和响应式数据的管理,需要的朋友可以参考下
    2024-11-11
  • 如何解决uni-app编译后 vendor.js 文件过大

    如何解决uni-app编译后 vendor.js 文件过大

    这篇文章主要介绍了如何解决uni-app编译后 vendor.js 文件过大的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • vue props传值失败 输出undefined的解决方法

    vue props传值失败 输出undefined的解决方法

    今天小编就为大家分享一篇vue props传值失败 输出undefined的解决方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • Vue中的计算属性和axios基本使用回顾

    Vue中的计算属性和axios基本使用回顾

    这篇文章主要介绍了Vue中的计算属性和axios基本使用回顾,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • 使用VitePress搭建及部署vue组件库文档的示例详解

    使用VitePress搭建及部署vue组件库文档的示例详解

    这篇文章主要介绍了使用VitePress搭建及部署vue组件库文档,本文以element-plus作为示例来搭建一个文档,结合实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • antd design table更改某行数据的样式操作

    antd design table更改某行数据的样式操作

    这篇文章主要介绍了antd design table更改某行数据的样式操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • elementPuls 表格反选实现示例代码

    elementPuls 表格反选实现示例代码

    这篇文章主要介绍了elementPuls 表格反选实现示例代码,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-07-07
  • vue3不同语法格式对比的实例代码

    vue3不同语法格式对比的实例代码

    vue3发布已有一段时间了,文档也大概看了一下,不过对于学一门技术,最好的方法还是实战,这篇文章主要给大家介绍了关于vue3不同语法格式对比的相关资料,需要的朋友可以参考下
    2021-08-08

最新评论