阅读 37

Vue3 组件注册(2)

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

1. 组件的名称

在通过 app.component 注册一个组件时,第一个参数是组件的名称,定义组件名的方式有两种:

  • 使用 kebab-case(短横线分隔命名)

    •   app.component('my-component-name', {
          /* ... */
        })
      复制代码
    • 当使用 kebab-case(短横线分隔命名)定义一个组件时,你也必须在引用这个自定义元素时使用 kebab-case,例如 <my-component-name>

  • 使用 PascalCase(首字母大写命名)

    •   app.component('MyComponentName', {
          /* ... */
        })
      复制代码
    • 当使用 PascalCase(首字母大写命名)定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。也就是说 <my-component-name><MyComponentName> 都是可接受的。但要注意,直接在 DOM(而不是在字符串模板或单文件组件中)中使用时只有 kebab-case 是有效的。

      <div id="app"></div>
      
      <template id="my-app">
       <!-- kebab-case 方式使用,没有问题 -->
       <component-c></component-c>
       <!-- 
         直接在 DOM 中,以 PascalCase 方式使用,会解析失败:
         [Vue warn]: Failed to resolve component: componentc 
       -->
       <ComponentC></ComponentC>
      </template>
      
      <template id="component-c">
       <h2>ComponentC</h2>
      </template>
      
      <script src="./js/vue.js"></script>
      <script>
       const App = {
         // template: '#my-app'
         // 在字符串模板中,以 PascalCase 方式使用,可以正常解析
         template: `<ComponentC></ComponentC>`
       };
      
       const app = Vue.createApp(App)
      
       // PascalCase 方式注册
       app.component('ComponentC', {
         template: '#component-c'
       })
       app.mount('#app');
      </script>
      复制代码

总之,不管是采用 kebab-case 方式还是 PascalCase 方式命名组件,我们在使用组件时一般都是通过 kebab-case 的方式引用的(在命名组件的时候则经常会用 PascalCase 方式命名)。而当直接在 DOM 中(而不是在字符串模板或单文件组件中)使用一个组件时,推荐遵循 W3C 规范来给自定义标签命名:

  1. 全部小写
  2. 有多个单词时,多个单词之间用连字符符号(-)连接

也就是采用 kebab-case 方式命名了。这样会帮助我们避免与当前以及未来的 HTML 元素发生冲突。

2. 注册局部组件

开发中,注册全局组件的情况较少,我们更多的是注册局部组件。

  • 全局组件往往是在应用程序一开始就会完成全局注册,这就意味着如果某些(全局)组件我们并没有用到,也会被注册
    • 比如我们注册了三个全局组件ComponentAComponentBComponentC
    • 而在开发中我们只使用了 ComponentAComponentB,即 ComponentC 没有被用到,但是我们已经在全局注册了 ComponentC,这就意味着类似于 Webpack 这种打包工具在打包我们的项目时,依然会对 ComponentC 进行打包
    • 这样最终打包出的 JavaScript 包就会有关于 ComponentC 的内容,这就会增加包的大小,导致用户下载的 JavaScript 的无谓的增加。
  • 所以在开发中我们通常采用局部注册的方式注册组件
    • 局部注册就是在我们需要使用到的组件中,通过 components 属性选项来进行注册;
    • 比如之前的 App 组件中,我们有 datacomputedmethods 等选项了,其实还可以有一个 components 选项
    • 这个 components 选项对应的是一个对象,对象中的键值对是“组件的名称: 组件对象”;

前面我们讲了全局注册组件的方式,比如全局注册一个 ComponentA 组件:

<div id="app"></div>

<template id="my-app">
  <component-a></component-a>
</template>

<template id="component-a">
  <h2>ComponentA</h2>
</template>

<script src="./js/vue.js"></script>
<script>
  const App = {
    template: '#my-app'
  };

  const ComponentA = {
    template: '#component-a'
  };

  const app = Vue.createApp(App);
  app.component('ComponentA', ComponentA);
  app.mount('#app');
</script>
复制代码

现在,如果我们希望注册一个 ComponentY 组件,它只在组件 ComponentX 中可以使用,那么就可以在 ComponentX 组件中局部注册 ComponentY 组件了。比如在 App 组件中局部注册 ComponentA 组件:

<div id="app"></div>

<template id="my-app">
  <component-a></component-a>
</template>

<template id="component-a">
  <h2>ComponentA</h2>
</template>

<script src="./js/vue.js"></script>
<script>
  const ComponentA = {
    template: '#component-a'
  };

  const App = {
    // 在 components 选项中局部注册组件
    components: {
      // key:组件名称
      // value:组件对象
      // key: value
      
      // ComponentA: ComponentA
      // ES6 增强的对象--属性值简写:
      ComponentA
    },
    template: '#my-app'
  };

  const app = Vue.createApp(App);
  app.mount('#app');
</script>
复制代码

这样一来,ComponentA 组件目前就只能在 App 组件中使用了。其它组件中如果也想使用这个 ComponentA 组件,也得先在它们的 components 选项中注册 ComponentA 组件才行。

关于组件化的更多内容我们会在脚手架中再讲,因为脚手架中我们会使用一个个独立的文件编写 Vue 相关的代码,那时代码结构会更加清晰。

文章分类
前端
文章标签